java PrintCompilation 输出:“made not entrant”的含义是什么?和“制造僵尸”

发布于 2024-09-03 00:53:43 字数 1056 浏览 2 评论 0原文

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

When running a Java 1.6 (1.6.0_03-b05) app I've added the -XX:+PrintCompilation flag. On the output for some methods, in particular some of those that I know are getting called a lot, I see the text made not entrant and made zombie.

What do these mean? Best guess is that it's a decompilation step before recompiling either that method or a dependency with greater optimisation. Is that true? Why "zombie" and "entrant"?

Example, with quite a bit of time between some of these lines:

[... 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]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

〃安静 2024-09-10 00:53:43

我在我的博客上整理了一些相关信息。我发现的悬崖点击评论说:

僵尸方法是指其代码因类加载而变得无效的方法。通常,服务器编译器会对非最终方法做出积极的内联决策。只要内联方法从未被覆盖,代码就是正确的。当加载子类并重写方法时,编译后的代码对于以后对其的所有调用都会被破坏。该代码被声明为“不可进入”(未来不会有损坏代码的调用者),但有时现有的调用者可以继续使用该代码。在内联的情况下,这还不够好;当现有调用者从嵌套调用返回代码时(或者只是在代码中运行时),它们的堆栈帧将被“去优化”。当不再有堆栈帧将 PC 放入损坏的代码中时,它被声明为“僵尸”——一旦 GC 处理它,就可以将其删除。

I've pulled together some info on this on my blog. A Cliff Click comment I found says:

Zombie methods are methods whose code has been made invalid by class loading. Generally the server compiler makes aggressive inlining decisions of non-final methods. As long as the inlined method is never overridden the code is correct. When a subclass is loaded and the method overridden, the compiled code is broken for all future calls to it. The code gets declared "not entrant" (no future callers to the broken code), but sometimes existing callers can keep using the code. In the case of inlining, that's not good enough; existing callers' stack frames are "deoptimized" when they return to the code from nested calls (or just if they are running in the code). When no more stack frames hold PC's into the broken code it's declared a "zombie" - ready for removal once the GC gets around to it.

八巷 2024-09-10 00:53:43

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

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

只是作为一个起点。

This is absolutely not an area of expertise for me, but I was interested and so did a bit of digging.

A couple of links you might find interesting: OpenJDK:nmethod.cpp, OpenJDK:nmethod.hpp.

A excerpt of 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); }
//...

Just as a starting place.

脸赞 2024-09-10 00:53:43

一个较新的解释是,日志中可以有这样的条目:

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

这实际上意味着在 第 3 层然后在层下4 已进一步优化,并且已不再进入 3-d 层;这意味着它将被第四层的代码替换。

A newer explanation is that there can be entries like this in log:

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

This actually means that one method (second here) has been compiled under tier level 3, then under tier level 4 it has been further more optimized and it has been made not entrant for the 3-d tier; meaning it will be replaced with code from the 4-th tier.

剧终人散尽 2024-09-10 00:53:43

这里有一个要点,其中包含有关 PrintCompilation 的大量信息。具体来说,它说:

当发生去优化时,如果决定使违规nmethod无效,则首先将其“设为不可进入”;然后,当NMethodSweeper发现堆栈上不再有它的激活时,它就“变成了僵尸”;

Here is a Gist with an unbelievable amount of information on PrintCompilation. Specifically, it says:

When deoptimization happens, if it is decided to invalidate the offending nmethod, it will be "made not entrant" first; and then, when the NMethodSweeper finds that there are no activations of it on the stacks any more, it is "made zombie";

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文