Joe*_*ney 40 java jit jvm-hotspot
运行Java 1.6(1.6.0_03-b05)应用程序时,我添加了-XX:+PrintCompilation
标志.在某些方法的输出中,特别是我知道的一些方法被大量调用,我看到了文本made not entrant
和made zombie
.
这些是什么意思?最好的猜测是,在重新编译该方法或具有更高优化的依赖项之前,它是一个反编译步骤.真的吗?为什么"僵尸"和"参赛者"?
例如,其中一些行之间有相当长的时间:
[... near the beginning]
42 jsr166y.LinkedTransferQueue::xfer (294 bytes)
[... much later]
42 made not entrant jsr166y.LinkedTransferQueue::xfer (294 bytes)
--- n sun.misc.Unsafe::compareAndSwapObject
170 jsr166y.LinkedTransferQueue::xfer (294 bytes)
170 made not entrant jsr166y.LinkedTransferQueue::xfer (294 bytes)
4% jsr166y.LinkedTransferQueue::xfer @ 29 (294 bytes)
171 jsr166y.LinkedTransferQueue::xfer (294 bytes)
[... even later]
42 made zombie jsr166y.LinkedTransferQueue::xfer (294 bytes)
170 made zombie jsr166y.LinkedTransferQueue::xfer (294 bytes)
171 made not entrant jsr166y.LinkedTransferQueue::xfer (294 bytes)
172 jsr166y.LinkedTransferQueue::xfer (294 bytes)
[... no further logs]
Run Code Online (Sandbox Code Playgroud)
Jod*_*hen 23
我在博客上汇总了一些相关信息.一个悬崖点击评论我发现说:
僵尸方法是通过类加载使代码无效的方法.通常,服务器编译器会对非最终方法做出积极的内联决策.只要内联方法永远不会被覆盖,代码就是正确的.当加载子类并重写该方法时,编译的代码将被中断,以便将来调用它.代码被声明为"not entrant"(没有未来的调用者来破坏代码),但有时现有的调用者可以继续使用代码.在内联的情况下,这不够好; 当现有调用者的堆栈帧从嵌套调用返回代码时(或者只是它们在代码中运行时)被"去优化".当没有更多的堆栈帧将PC保存到损坏的代码中时,它被声明为"僵尸" - 一旦GC到达它就准备好移除它.
这对我来说绝对不是一个专业领域,但我很感兴趣,所以做了一些挖掘.
您可能会发现一些有趣的链接:OpenJDK:nmethod.cpp,OpenJDK:nmethod.hpp.
摘录nmethod.hpp
:
// Make the nmethod non entrant. The nmethod will continue to be
// alive. It is used when an uncommon trap happens. Returns true
// if this thread changed the state of the nmethod or false if
// another thread performed the transition.
bool make_not_entrant() { return make_not_entrant_or_zombie(not_entrant); }
//...
Run Code Online (Sandbox Code Playgroud)
就像一个起点.
更新的解释是在日志中可以有这样的条目:
129 72 3 EscapeAnalysysTest::second (24 bytes)
.......... some more lines
135 76 4 EscapeAnalysysTest::second (24 bytes)
137 74 3 EscapeAnalysysTest::second (24 bytes) made not entrant
Run Code Online (Sandbox Code Playgroud)
这实际上意味着一个方法(second
这里)已经在层级3下编译,然后在层级下4
进一步优化,并且它已经不能进入三维层; 意味着它将被替换为第4层的代码.