java PrintCompilation输出:“make not entrant”和“made zombie”是什么意思

时间:2010-05-28 16:41:41

标签: java jit jvm-hotspot

运行Java 1.6(1.6.0_03-b05)应用程序时,我添加了-XX:+PrintCompilation标志。在某些方法的输出中,特别是我知道的一些方法被大量调用,我看到了文本made not entrantmade 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]

4 个答案:

答案 0 :(得分:23)

我在my blog上汇总了一些相关信息。我找到的Cliff Click评论说:

  

Zombie方法是通过类加载使代码无效的方法。通常,服务器编译器会对非最终方法做出积极的内联决策。只要内联方法永远不会被覆盖,代码就是正确的。当加载子类并重写该方法时,编译的代码将被中断,以便将来调用它。代码被声明为“not entrant”(没有未来的调用者来破坏代码),但有时现有的调用者可以继续使用代码。在内联的情况下,这不够好;当现有调用者的堆栈帧从嵌套调用返回代码时(或者只是它们在代码中运行时)被“去优化”。当没有更多的堆栈帧将PC保存到损坏的代码中时,它被声明为“僵尸” - 一旦GC到达它就可以移除它。

答案 1 :(得分:9)

这对我来说绝对不是一个专业领域,但我很感兴趣,所以做了一些挖掘。

您可能会发现一些有趣的链接:OpenJDK:nmethod.cppOpenJDK: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); }
//...

就像一个起点。

答案 2 :(得分:6)

更新的解释是在日志中可以有这样的条目:

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

这实际上意味着一个方法(此处为second已在tier level 3下编译,然后在层级4下进行了进一步优化,它已被非参赛者用于3-d层;意味着它将被替换为第4层的代码。

答案 3 :(得分:2)

Here is a GistPrintCompilation上提供了令人难以置信的大量信息。具体来说,它说:

  

当进行去优化时,如果决定使有问题的nmethod无效,那么它将首先“不进入”;然后,当NMethodSweeper发现堆栈上没有激活它时,它就是“制造僵尸”;