thread generate java jvm jstack

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.