例如,一个方法中有10000次循环。运行1000次时,backedge_counter触发JIT
编译。并且解释器继续执行。当它循环 4000次次时,JIT
编译完成。
我的问题是,如何通过解释器执行剩余的其余6,000 次,或执行 native 代码?或者在下一次调用此方法之前不执行 native 代码?
下次调用此方法时会发生什么?
最佳答案
假设您询问的是HotSpot JVM,答案是剩余的交互将以编译的代码执行。
HotSpot JVM具有一种称为“栈上替换”的技术,可以在方法运行时从解释器转换为编译后的代码。
http://openjdk.java.net/groups/hotspot/docs/HotSpotGlossary.html
如果使用-XX:+PrintCompilation
标志运行JVM,则OSR编译将以%
符号进行标记:
274 27 3 java.lang.String::lastIndexOf (52 bytes)
275 29 3 java.lang.String::startsWith (72 bytes)
275 28 3 java.lang.String::startsWith (7 bytes)
275 30 3 java.util.Arrays::copyOf (19 bytes)
276 32 4 java.lang.AbstractStringBuilder::append (29 bytes)
276 31 s 3 java.lang.StringBuffer::append (13 bytes)
283 33 % 3 LoopTest::myLongLoop @ 13 (43 bytes)
^ ^
OSR bytecode index of OSR entry
更新
通常,在OSR编译之后,还会对常规编译进行排队,以便下次调用该方法时,它将开始直接在编译模式下运行。
187 32 % 3 LoopTest::myLongLoop @ 13 (43 bytes)
187 33 3 LoopTest::myLongLoop (43 bytes)
但是,如果在再次调用该方法时常规编译尚未完成,则该方法将开始在解释器中运行,然后在循环内切换到OSR条目。