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 g
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.
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 theNMethodSweeper
finds that there are no activations of it on the stacks any more, it is "made zombie";
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.
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.