关于HotSpot JVM JIT的困惑

Bol*_*ang 4 java jit jvm hotspot

例如,方法中有10000次循环.当它运行1000次时,backingge_counter会触发JIT编译.解释器继续执行.当它循环4000次时,JIT编译完成.

我的问题是,如何通过解释器执行剩余6000次或执行本机代码?或者在下次调用此方法之前不执行本机代码?下次调用此方法时会发生什么?

apa*_*gin 9

假设您询问HotSpot JVM,答案是剩余的交互将在编译的代码中执行.

HotSpot JVM有一种称为"堆栈内替换"的技术,可在方法运行时从解释器切换到编译代码.

http://openjdk.java.net/groups/hotspot/docs/HotSpotGlossary.html

堆叠替换
也称为"OSR".将解释(或不太优化)的堆栈帧转换为编译(或更优化)的堆栈帧的过程.当解释器发现方法正在循环时,会发生这种情况,请求编译器生成一个特殊的nmethod,其中循环中的某个入口点(特别是在后向分支处),并将控制转移到该nmethod.与去优化的粗略逆转.

如果使用-XX:+PrintCompilationflag 运行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
Run Code Online (Sandbox Code Playgroud)

UPDATE

通常在OSR编译之后,常规编译也会排队,因此下次调用该方法时,它将直接以编译模式运行.

    187   32 %     3       LoopTest::myLongLoop @ 13 (43 bytes)
    187   33       3       LoopTest::myLongLoop (43 bytes)
Run Code Online (Sandbox Code Playgroud)

但是,如果在再次调用该方法时未完成常规编译,则该方法将在解释器中开始运行,然后将切换到循环内的OSR条目.