运行Java 1.6(1.6.0_03-b05)应用程序时,我添加了该-XX:+PrintCompilation标志。在某些方法的输出上,尤其是我所知道的一些方法被称为很多,我看到了文本made not entrant和made zombie。
-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]
我已经在自己的博客上整理了一些相关信息。我发现的Cliff Click评论说:
僵尸方法是通过类加载使其代码无效的方法。通常,服务器编译器会针对非最终方法做出积极的内联决策。只要内联方法永远不会被覆盖,代码就是正确的。当子类被加载并且方法被重写时,编译后的代码将为以后的所有调用而中断。该代码被声明为“不可进入”(将来的调用者不再调用该损坏的代码),但是有时现有的调用者可以继续使用该代码。就内联而言,这还不够好;现有调用者的堆栈帧从嵌套调用返回到代码时(或仅在代码中运行时)被“优化”。如果没有更多的堆栈框架将PC固定在已损坏的代码中,则将其声明为“僵尸”-一旦GC解决了该问题,便可以将其删除。