kill -3 para obtener el volcado de hilo de Java

116

estoy usando kill -3 comando para ver el volcado de subprocesos de la JVM en unix. Pero, ¿dónde puedo encontrar el resultado de este killcomando? ¡¡Estoy perdido!!

javanerd
fuente
¿Qué proceso estás matando? ¿Es un servidor de aplicaciones J2EE? Si es el caso, debería encontrar el seguimiento de la pila en la salida estándar.
Luciano Fiandesio
Estoy matando un proceso que ejecuta la clase java
javanerd
2
No debería escribir el volcado de hilo en la consola. ya que la clase java tiene la consola como salida
estándar

Respuestas:

194

Alternativamente, puede usar jstack (incluido con JDK) para realizar un volcado de subprocesos y escribir la salida donde desee. ¿No está disponible en un entorno Unix?

jstack PID > outfile
Joshua McKinnon
fuente
1
Sí, en el momento en que se ejecuta. También puede especificar -l (L minúscula) para una lista larga que imprime información de bloqueo adicional
Joshua McKinnon
2
Hasta que el comando jstack falle constantemente debido a "No se puede deducir el tipo de hilo de la dirección" ;-(
noahlz
1
Si ve ese error, le sugiero que lo consulte con su proveedor. Una búsqueda rápida muestra, por ejemplo, que hay un error abierto en RHEL con respecto a este error y openjdk ...
Joshua McKinnon
7
Vale la pena señalar que jstack requiere el JDK. Si está ejecutando aplicaciones en un servidor que solo tiene JRE instalado, deberá encontrar otro medio para el volcado de subprocesos.
jeffkempf
1
A continuación se explica cómo usar jstack para obtener el volcado de subprocesos de un proceso que se ejecuta con un usuario diferente, como el servicio de Windows: stackoverflow.com/questions/1197912/…
Vadzim
44

El volcado de subprocesos se escribe en el sistema desde la máquina virtual en la que ejecutó kill -3. Si está redirigiendo la salida de la consola de la JVM a un archivo, el volcado de subprocesos estará en ese archivo. Si la JVM se está ejecutando en una consola abierta, el volcado de hebras se mostrará en su consola.

Kris Babic
fuente
1
Hay una forma de redirigir la salida del volcado de subprocesos de JVM a un archivo separado. Vea en mi respuesta.
Vadzim
32

Hay una manera de redirigir la salida de volcado de subprocesos de JVM en la señal de interrupción a un archivo separado con la opción de diagnóstico LogVMOutput :

-XX:+UnlockDiagnosticVMOptions -XX:+LogVMOutput -XX:LogFile=jvm.log
Vadzim
fuente
5
Técnicamente, esto no "redirige" la salida de volcado de subprocesos. Activa el registro de JVM en jvm.log (que incluye la salida de volcado de subprocesos) pero kill -QUIT seguirá volcando a la salida estándar del proceso (también). Voto a favor de la descripción de opciones oscuras de JVM :)
sqweek
25

Con Java 8 en la imagen, jcmdes el enfoque preferido.

jcmd <PID> Thread.print

A continuación se muestra el fragmento de la documentación de Oracle :

El lanzamiento de JDK 8 introdujo Java Mission Control, Java Flight Recorder y la utilidad jcmd para diagnosticar problemas con aplicaciones JVM y Java. Se sugiere utilizar la última utilidad, jcmd en lugar de la utilidad jstack anterior para mejorar el diagnóstico y reducir la sobrecarga de rendimiento.

Sin embargo, enviar esto con la aplicación puede tener implicaciones de licencia de las que no estoy seguro.

Arnab Biswas
fuente
1
Desafortunadamente, jcmdno se puede conectar al proceso de servicio de Windows com.sun.tools.attach.AttachNotSupportedException: Insufficient memory or insufficient privileges to attachmientras jstack -Ftiene éxito: stackoverflow.com/questions/1197912/…
Vadzim
1
Debe ejecutar jcmd <pid> Thread.dump con el mismo usuario que tiene el proceso java; de lo contrario, sus conexiones se eliminarán. Ver stackoverflow.com/questions/25438983/…
Twilite
11

En la misma ubicación donde se coloca la salida estándar de la JVM. Si tiene un servidor Tomcat, este será el catalina_(date).outarchivo.

Daniel
fuente
8

Cuando se usa kill -3, se debería ver el volcado de subprocesos en la salida estándar. La mayoría de los servidores de aplicaciones escriben la salida estándar en un archivo separado. Debería encontrarlo allí cuando use kill -3. Hay varias formas de obtener volcados de hilo:

  • kill -3 <PID>: Da salida a salida estándar.
  • Si uno tiene acceso a la ventana de la consola donde se ejecuta el servidor, puede usar Ctrl+ Breakcombinación de teclas para generar el seguimiento de la pila en STDOUT.
  • Para las VM de hotspot también podemos usar el jstackcomando para generar un volcado de hilo. Es parte del JDK. La sintaxis es la siguiente:

    Usage:
    
    jstack [-l] <pid> (to connect to running process)
    jstack -F [-m] [-l] <pid>(to connect to a hung process)
    
     - For JRockit JVM we can use JRCMD command which comes with JDK Syntax: 
       jrcmd <jrockit pid> [<command> [<arguments>]] [-l] [-f file] [-p] -h]
Apoorve
fuente
Tengo problemas para usar Kill -3 <PID>. Funciona bien, pero también mata el proceso después de escribir el volcado de hilo en la consola. ¿Se supone que hace eso?
Ashley
@Ashley: no kill -3 <PID>, no debería matar a la JVM. ¿Qué tipo de aplicación Java estás viendo?
slm
2

En Jboss puedes realizar lo siguiente

nohup $JBOSS_HOME/bin/run.sh -c  yourinstancename $JBOSS_OPTS >> console-$(date +%Y%m%d).out  2>&1 < /dev/null &
kill -3 <java_pid>

Esto redirigirá su salida / subproceso a la consola de archivos especificada en el comando anterior.

anish
fuente
2
  1. Encuentra el ID de proceso [ID de PS]
  2. Ejecute jcmd [ID de PS] Thread.print
Mehmet Erdemsoy
fuente
2

Pasos que debe seguir si desea el volcado de subprocesos de su proceso StandAlone Java

Paso 1: Obtenga el ID de proceso para el script de shell que llama al programa java

linux$ ps -aef | grep "runABCD"

user1  **8535**  4369   0   Mar 25 ?           0:00 /bin/csh /home/user1/runABCD.sh

user1 17796 17372   0 08:15:41 pts/49      0:00 grep runABCD

Paso 2: Obtenga el ID de proceso para el niño que fue invocado por runABCD. Utilice el PID anterior para obtener los niños.

linux$ ps -aef | grep **8535**

user1  **8536**  8535   0   Mar 25 ?         126:38 /apps/java/jdk/sun4/SunOS5/1.6.0_16/bin/java -cp /home/user1/XYZServer

user1  8535  4369   0   Mar 25 ?           0:00 /bin/csh /home/user1/runABCD.sh

user1 17977 17372   0 08:15:49 pts/49      0:00 grep 8535

Paso 3: obtenga el JSTACK para el proceso en particular. Obtenga el ID de proceso de su proceso XYSServer. es decir 8536

linux$ jstack **8536** > threadDump.log
Mella
fuente