编译与解释共存的java
解释
- jvm解释执行由javac生成的class字节码
编译
- 热点代码通过JIT编译器走编译路线
编译VS解释
编译这种方式速度快不是说编译这个过程本身速度快,而是体现在通过编译生成的机器码可以重复利用,如果代码只执行一遍,解释的方式更快
编译过程(以HotSpot为例)
JIT在最初(JVM刚启动时)并不开始编译
热点代码检测
方法
采样
- 周期性检测线程栈的栈顶,经常出现在栈顶的方法是热点方法
计数器
为每个方法甚至是代码块建立计数器,调用一次就加一,超过某个阈值就排队编译
- 方法调用计数器
- 回边计数器(循环)
对比
- 周期性检测栈顶得到的结果是执行时间最长的代码而不是使用频率最高的代码,采样法容易受阻塞影响
- 计数器法粒度更细,但更麻烦
开始编译、无缝替换
问题
采用计数器法检测热点代码,如果遇到死循环(良性),这个方法对应的计数器可能永远不会加一
解决
- 循环执行完一次两个计数器都会加一
- 栈上替换技术,编译版本和解释版本无缝替换