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

Joe*_*ney 40 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]
Run Code Online (Sandbox Code Playgroud)

Jod*_*hen 23

我在博客上汇总了一些相关信息.一个悬崖点击评论我发现说:

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

  • Kris Mok写了一篇回复JodaStephen的文章,该文章现已与他的博客相关联,并且在其对-XX:+ PrintCompilation的描述中更为完整.这是链接:https://gist.github.com/1165804#file_notes.md (8认同)

Mar*_*ers 9

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

您可能会发现一些有趣的链接: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)

就像一个起点.

  • 鉴于"参与者"的意思我的*猜*将标记编译的方法不再*进入*(虽然一些线程可能仍然在其中),而僵尸意味着它没有进一步的使用,可以处理.就像收银台可以宣布它不接受新客户(非参赛者)但仍然必须在关闭收银台(僵尸)之前为排队的客户提供服务.但这只是猜测. (3认同)

Eug*_*ene 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
Run Code Online (Sandbox Code Playgroud)

这实际上意味着一个方法(second这里)已经在层级3下编译,然后在层级下4进一步优化,并且它已经不能进入三维层; 意味着它将被替换为第4层的代码.