小编典典

java PrintCompilation输出:“不进入”和“僵尸”的含义是什么

java

运行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]

阅读 319

收藏
2020-12-03

共1个答案

小编典典

我已经在自己的博客上整理了一些相关信息。我发现的Cliff Click评论说:

僵尸方法是通过类加载使其代码无效的方法。通常,服务器编译器会针对非最终方法做出积极的内联决策。只要内联方法永远不会被覆盖,代码就是正确的。当子类被加载并且方法被重写时,编译后的代码将为以后的所有调用而中断。该代码被声明为“不可进入”(将来的调用者不再调用该损坏的代码),但是有时现有的调用者可以继续使用该代码。就内联而言,这还不够好;现有调用者的堆栈帧从嵌套调用返回到代码时(或仅在代码中运行时)被“优化”。如果没有更多的堆栈框架将PC固定在已损坏的代码中,则将其声明为“僵尸”-一旦GC解决了该问题,便可以将其删除。

2020-12-03