考虑这个小班:
public class Example {
public int plus(int a){
int b;
b = 1;
return b+a;
}
}
javap说:
public int plus(int);
descriptor: (I)I
flags: ACC_PUBLIC
Code:
stack=2, locals=3, args_size=2
0: iconst_1
1: istore_2
2: iload_2
3: iload_1
4: iadd
5: ireturn
LineNumberTable:
line 4: 0
line 5: 2
我不明白为什么我们需要第1行和第2行?
我听说Java Runtime环境会计算函数调用,如果它们超过一定数量的调用就会编译函数。
这是否意味着Java编译器将所有优化都留给了字节码编译器?例如。 Java程序开始变慢并且随着时间的推移变得更快?
请解释一下!
答案 0 :(得分:3)
首先,您正在查看字节码编译器的输出。典型的Java字节码编译器几乎不做任何优化。重量级优化由JIT编译器在运行时完成。
因此,javap -c
显示的内容是未经优化的字节码。
我不明白为什么我们需要第1行和第2行?
您正在查看未经优化的字节码。前2条指令将1
分配给局部变量b
。我们可以看到局部变量可以很容易地被优化掉。但是字节码编译器(javac
)不会打扰。
我听说Java Runtime环境会计算函数调用,如果它们超过一定数量的调用就会编译函数。
这就是典型的Hotspot JVM的工作原理。
这是否意味着Java编译器将所有优化都留给了字节码编译器?
没有。 JIT编译器执行运行时编译和相关优化。
字节码编译器将Java源代码编译为字节码。 JIT编译器在运行时将字节码编译为本机代码。
E.g。 Java程序开始变慢并且随着时间的推移变得更快?
这是正确的。初始字节码解释阶段和JIT编译是所谓的“JVM预热”的一部分。
(根据要求......)
字节码编译器未优化的原因包括:
JIT编译器进行优化的原因包括:
最后,JIT编译与Java的后期绑定模型很吻合。