I want to get some insights of Java java.lang.ref.Finalizer
initializing process so I set a breakpoint on its class static block:
static {
-> ThreadGroup tg = Thread.currentThread().getThreadGroup(); // breakpoint set on this line
for (ThreadGroup tgn = tg;
tgn != null;
tg = tgn, tgn = tg.getParent());
Thread finalizer = new FinalizerThread(tg);
finalizer.setPriority(Thread.MAX_PRIORITY - 2);
finalizer.setDaemon(true);
finalizer.start();
}
Then start an empty main()
method via IntelliJ IDEA debug button, but the breakpoint never stops the program (JVM just executes to its end and exits.)
Java version:
openjdk version "1.8.0_302"
OpenJDK Runtime Environment Corretto-8.302.08.1 (build 1.8.0_302-b08)
OpenJDK 64-Bit Server VM Corretto-8.302.08.1 (build 25.302-b08, mixed mode)
Why this breakpoint not taking effect?
Since JDK 5.0, the JVM debugging capability has been constructed based on JVM TI which replaces the JVMPI and JVMDI. I'm not familiar with JVMDI thus the following statements are based on the fact you debug the code using agentlib:jdwp
like:
-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005
The jdwp agent (loaded from libjdwp.so
file) bind the port specified (5005 in the above example) on receiving post_vm_initialized
event. As the event name indicates, VM has been initialized and the Finalizer
class has already been loaded when the debug port binding happens (of course you can only debug Java codes after JDWP port listening). So you cannot debug the static block code of Finalizer
. In fact, classes loaded before JDWP port binding all are not debuggable in terms of initialization. But if thread runs in the code of the loaded-before classes afterwards, you're still able to debug it, for example the Finalizer.FinalizerThread#run
method.
I found a quote from The JVM Tool Interface (JVM TI): How VM Agents Work:
The library is loaded before the VM has initialized, allowing the agent library to capture early VM events that it could not access before.
JDWP agentlib may bind the port on the other hand in Agent_Onload
function (in debugInit.c
), which may allow the debugging for all classes loading in JVM (I guess).
PS: if you are interested in the code mentioned above (in OpenJDK 8 with Mercurial ID dcb218f54ca1):
post_vm_initialized
event processing in function debugInit.c:initialize
.Agent_Onload
function also locates in code file debugInit.c
.