关于JIT与OSR:编译基于方法还是代码?JVM编译机制疑问
关于JVM OSR编译与方法全编译的问题解答
问题1:非热点方法中的热点循环是否会触发OSR编译,且下次调用能否复用编译后的循环代码?
- 会触发OSR(栈上替换)编译。当循环的回跳次数达到JVM设定的阈值(如HotSpot默认约10000次),即使整个方法的调用次数未达到全编译标准,JVM会单独编译该循环体,并在循环执行过程中完成栈上替换,让后续迭代直接运行编译后的机器码。
- 下次调用该方法时,循环初始阶段仍会以解释模式执行,直到循环回跳次数再次触发阈值,才会切换到之前编译好的OSR代码。如果后续方法整体热度达标触发全方法编译,之后整个方法(包含循环)会直接运行全编译后的代码,无需再走OSR切换流程。
问题2:非热点但含热点循环的方法,是否会先触发OSR编译,再触发全方法编译?
- 是的,这种情况完全可能发生。JVM的方法调用计数器与循环回跳计数器独立统计但相互关联:
- 当循环回跳次数先达到阈值,会优先触发循环体的OSR编译;
- 后续随着方法调用次数增加,或循环执行带来的热度累积,当方法整体热度(不同JVM计算逻辑略有差异,HotSpot中会结合调用次数与循环执行的间接热度)达到全方法编译阈值时,就会触发整个方法的标准编译。
- 一旦全方法编译完成,后续调用该方法将直接进入编译后的机器码执行,不再需要先解释执行循环再进行OSR替换。
内容的提问来源于stack exchange,提问作者Steven Dallas
相关产品推荐
相关产品推荐

