java - generate - jstack thread state
¿Cómo afecta jstack-F a un proceso Java en ejecución? (2)
Estoy intentando diagnosticar un problema donde una aplicación web de Java que estoy usando (Jenkins) deja de responder. Si ejecuto jstack
sin el indicador -F
, no me da nada, pero si pongo el indicador para forzar un volcado de subprocesos no solo obtengo un resultado, sino que la aplicación comienza a responder y continúa como si no hubiera pasado nada. hasta que finalmente deja de responder de nuevo.
¿Qué hace la jstack -F
que afectaría a una JVM en ejecución y causaría que una aplicación que no responde comience a responder nuevamente?
Puedes ver la fuente de jstack here . El argumento -F cambia la forma en que jstack se conecta a jvm. Con -F (o -m) JStack se conecta a jvm mediante la interfaz del depurador de Java. Si se especifica un pid, JStack se conecta con el conector de conexión PID de SA que dice:
El proceso de depuración no debe haberse iniciado en modo de depuración (es decir, con -agentlib: jdwp o -Xrunjdwp). Es permisible que el proceso se cuelgue .
No sé por qué causaría que una aplicación que no responde comience a responder de nuevo, pero el enlace de arriba también dice:
El proceso se suspende cuando este conector se conecta y se reanuda cuando este conector se desconecta.
Esto puede tener un efecto.
jstack -F -l pid es similar a (asumiendo que el directorio de trabajo es JAVA_HOME)
bin/java -Dsun.jvm.hotspot.debugger.useWindbgDebugger -Dsun.jvm.hotspot.debugger.useProcDebugger -cp lib/sa-jdi.jar;lib/tools.jar sun.tools.jstack.JStack -F -l pid
y en el código sun.tools.jstack.JStack
if (arg.equals("-F")) {
useSA = true;
}
.....
// now execute using the SA JStack tool or the built-in thread dumper
if (useSA) {
// parameters (<pid> or <exe> <core>
...
runJStackTool(mixed, locks, params);
} else {
// pass -l to thread dump operation to get extra lock info
String pid = args[optionCount];
...
runThreadDump(pid, params);
}
y como se pasa -F, se ejecuta runStockTool para cargar sun.jvm.hotspot.tools.JStack, tiene el mismo efecto de invocar directamente
bin/java -Dsun.jvm.hotspot.debugger.useWindbgDebugger -Dsun.jvm.hotspot.debugger.useProcDebugger -cp lib/sa-jdi.jar;lib/tools.jar sun.jvm.hotspot.tools.JStack pid
y sun.jvm.hotspot.tools.JStack llamará sun.jvm.hotspot.bugspot.BugSpotAgent attach -> ir -> método setupVM
Tal vez el código de abajo es la magia
jvmdi = new ServiceabilityAgentJVMDIModule(debugger, saLibNames);
if (jvmdi.canAttach()) {
jvmdi.attach();
jvmdi.setCommandTimeout(6000);
debugPrintln("Attached to Serviceability Agent''s JVMDI module.");
// Jog VM to suspended point with JVMDI module
resume();
suspendJava();
suspend();
debugPrintln("Suspended all Java threads.");
}
suspenderá todos los hilos de Java en el proceso de destino. Si su aplicación se cuelga por inanición de subprocesos, la llamada al método de suspensión puede relajarlos.