例如,一个方法中有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条目。

09-26 17:14