62,629
社区成员
发帖
与我相关
我的任务
分享import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
for ( int i = 0 ; i < 100 ; i++ ) {
list.add( "num-" + i );
}
String element = null;
for ( int i = 0 , k = list.size() ; i < k ; i++ ) {
element = list.get( i );
System.out.println( System.identityHashCode( element ) );
}
}
}
第二种方式代码:
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
for ( int i = 0 ; i < 100 ; i++ ) {
list.add( "num-" + i );
}
for ( int i = 0 , k = list.size() ; i < k ; i++ ) {
String element = list.get( i );
System.out.println( System.identityHashCode( element ) );
}
}
}
使用 javap -c Test 查看 JVM 指令(第一种方式):
H:\tmp>javap -c Test
Compiled from "Test.java"
public class Test extends java.lang.Object{
public Test();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: new #2; //class java/util/ArrayList
3: dup
4: invokespecial #3; //Method java/util/ArrayList."<init>":()V
7: astore_1
8: iconst_0
9: istore_2
10: iload_2
11: bipush 100
13: if_icmpge 48
16: aload_1
17: new #4; //class java/lang/StringBuilder
20: dup
21: invokespecial #5; //Method java/lang/StringBuilder."<init>":()V
24: ldc #6; //String num-
26: invokevirtual #7; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava
29: iload_2
30: invokevirtual #8; //Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuild
33: invokevirtual #9; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
36: invokeinterface #10, 2; //InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
41: pop
42: iinc 2, 1
45: goto 10
48: aconst_null
49: astore_2
50: iconst_0
51: istore_3
52: aload_1
53: invokeinterface #11, 1; //InterfaceMethod java/util/List.size:()I
58: istore 4
60: iload_3
61: iload 4
63: if_icmpge 93
66: aload_1
67: iload_3
68: invokeinterface #12, 2; //InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
73: checkcast #13; //class java/lang/String
76: astore_2
77: getstatic #14; //Field java/lang/System.out:Ljava/io/PrintStream;
80: aload_2
81: invokestatic #15; //Method java/lang/System.identityHashCode:(Ljava/lang/Object;)I
84: invokevirtual #16; //Method java/io/PrintStream.println:(I)V
87: iinc 3, 1
90: goto 60
93: return
}
48:获取 null 值
49:将 null 压入 astore_2 区域
这两个指令相当于:String line = null;
68:从 List 中获取 i 的值
73:类型检查
76:将值的地址压入 astore_2 区域
第二种方式的 JVM 指令:
Compiled from "Test.java"
public class Test extends java.lang.Object{
public Test();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: new #2; //class java/util/ArrayList
3: dup
4: invokespecial #3; //Method java/util/ArrayList."<init>":()V
7: astore_1
8: iconst_0
9: istore_2
10: iload_2
11: bipush 100
13: if_icmpge 48
16: aload_1
17: new #4; //class java/lang/StringBuilder
20: dup
21: invokespecial #5; //Method java/lang/StringBuilder."<init>":()V
24: ldc #6; //String num-
26: invokevirtual #7; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava
29: iload_2
30: invokevirtual #8; //Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuild
33: invokevirtual #9; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
36: invokeinterface #10, 2; //InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
41: pop
42: iinc 2, 1
45: goto 10
48: iconst_0
49: istore_2
50: aload_1
51: invokeinterface #11, 1; //InterfaceMethod java/util/List.size:()I
56: istore_3
57: iload_2
58: iload_3
59: if_icmpge 91
62: aload_1
63: iload_2
64: invokeinterface #12, 2; //InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
69: checkcast #13; //class java/lang/String
72: astore 4
74: getstatic #14; //Field java/lang/System.out:Ljava/io/PrintStream;
77: aload 4
79: invokestatic #15; //Method java/lang/System.identityHashCode:(Ljava/lang/Object;)I
82: invokevirtual #16; //Method java/io/PrintStream.println:(I)V
85: iinc 2, 1
88: goto 57
91: return
}
64:从 List 中获取 i 的值
69:类型检查
72:将值的地址压入 astore_4 区域
从两种不同风格不同的 JVM 指令来说,几乎没有区别,我不知道楼上的各位何来第一种性能高的说法?
变量的内存分配是在栈空间做的,而栈空间的操作是在编译时确定的。对于 JVM 来说,只是将堆中对象的内存地址压入栈空间中。
对于编译时内联处理,以及 GC 的垃圾处理来说,尽量将局变量的作用域减少到最小的范围之内!