1. Información general
En este tutorial, discutiremos varias formas de capturar el volcado de subprocesos de una aplicación Java.
Un volcado de subprocesos es una instantánea del estado de todos los subprocesos de un proceso Java . El estado de cada hilo se presenta con un seguimiento de pila, que muestra el contenido de la pila de un hilo. Un volcado de hilo es útil para diagnosticar problemas ya que muestra la actividad del hilo. Los volcados de subprocesos se escriben en texto plano, por lo que podemos guardar su contenido en un archivo y verlos más tarde en un editor de texto .
En las siguientes secciones, veremos varias herramientas y enfoques para generar un volcado de subprocesos.
2. Uso de las utilidades de JDK
El JDK proporciona varias utilidades que pueden capturar el volcado de subprocesos de una aplicación Java. Todas las utilidades se encuentran en la carpeta bin dentro del directorio de inicio de JDK . Por lo tanto, podemos ejecutar estas utilidades desde la línea de comandos siempre que este directorio esté en la ruta de nuestro sistema.
2.1. jstack
jstack es una utilidad JDK de línea de comandos que podemos usar para capturar un volcado de subprocesos. Toma el pid de un proceso y muestra el volcado de subprocesos en la consola. Alternativamente, podemos redirigir su salida a un archivo.
Echemos un vistazo a la sintaxis de comandos básica para capturar un volcado de hilo usando jstack:
jstack [-F] [-l] [-m]
Todas las banderas son opcionales. Veamos qué significan:
- La opción -F fuerza un volcado de hilo; práctico de usar cuando jstack pid no responde (el proceso está bloqueado)
- La opción -l indica a la utilidad que busque sincronizadores que se puedan poseer en el montón y bloquee
- -m opción imprime marcos de pila nativos (C y C ++) además de los marcos de pila de Java
Usemos este conocimiento capturando un volcado de hilo y redirigiendo el resultado a un archivo:
jstack 17264 > /tmp/threaddump.txt
Recuerde que podemos obtener fácilmente el pid de un proceso de Java usando el comando jps .
2.2. Control de misión de Java
Java Mission Control (JMC) es una herramienta GUI que recopila y analiza datos de aplicaciones Java. Después de lanzar JMC, muestra la lista de procesos Java que se ejecutan en una máquina local. También podemos conectarnos a procesos Java remotos a través de JMC.
Podemos hacer clic derecho en el proceso y hacer clic en la opción " Iniciar grabación de vuelo ". Después de esto, la pestaña Threads muestra los Thread Dumps:

2.3. jvisualvm
jvisualvm es una herramienta con una interfaz gráfica de usuario que nos permite monitorear, solucionar problemas y perfilar aplicaciones Java . La GUI es simple pero muy intuitiva y fácil de usar.
Una de sus muchas opciones nos permite capturar un volcado de hilo. Si hacemos clic derecho en un proceso de Java y seleccionamos la opción "Volcado de hilo" , la herramienta creará un volcado de hilo y lo abrirá en una nueva pestaña:

A partir de JDK 9, Visual VM no se incluye en las distribuciones de Oracle JDK y Open JDK. Por lo tanto, si usamos Java 9 o versiones más recientes, podemos obtener JVisualVM del sitio del proyecto de código abierto de Visual VM.
2.4. jcmd
jcmd es una herramienta que funciona enviando solicitudes de comando a la JVM. Aunque es potente, no contiene ninguna funcionalidad remota ; tenemos que usarlo en la misma máquina donde se ejecuta el proceso de Java.
Uno de sus muchos comandos es Thread.print . Podemos usarlo para obtener un volcado de hilo simplemente especificando el pid del proceso:
jcmd 17264 Thread.print
2.5. jconsole
jconsole nos permite inspeccionar el seguimiento de la pila de cada hilo. Si abrimos jconsole y nos conectamos a un proceso Java en ejecución, podemos navegar a la pestaña Threads y encontrar el seguimiento de la pila de cada thread :

2.6. Resumen
Resulta que hay muchas formas de capturar un volcado de subprocesos utilizando las utilidades JDK. Tomemos un momento para reflexionar sobre cada uno y describa sus pros y contras:
- jstack : proporciona la forma más rápida y sencilla de capturar un volcado de hilo. Sin embargo, hay mejores alternativas disponibles a partir de Java 8
- jmc : herramienta mejorada de diagnóstico y generación de perfiles JDK. Minimiza la sobrecarga de rendimiento que suele ser un problema con las herramientas de creación de perfiles.
- jvisualvm : herramienta de creación de perfiles ligera y de código abierto con una excelente consola GUI
- jcmd : extremadamente potente y recomendado para Java 8 y posteriores. Una sola herramienta que sirve para muchos propósitos: captura de volcado de subprocesos ( jstack ), volcado de montón ( jmap ), propiedades del sistema y argumentos de la línea de comandos ( jinfo )
- jconsole : vamos a inspeccionar la información de seguimiento de la pila de subprocesos
3. Desde la línea de comandos
En los servidores de aplicaciones empresariales, solo se instala JRE por razones de seguridad. Por lo tanto, no podemos usar las utilidades mencionadas anteriormente ya que son parte de JDK. Sin embargo, existen varias alternativas de línea de comandos que nos permiten capturar volcados de subprocesos fácilmente.
3.1. comando kill -3 (Linux / Unix)
La forma más fácil de capturar un volcado de subprocesos en sistemas similares a Unix es mediante el comando kill , que podemos usar para enviar una señal a un proceso mediante la llamada al sistema kill () . En este caso de uso, le enviaremos la señal -3 .
Usando nuestro mismo pid de ejemplos anteriores, echemos un vistazo a cómo usar kill para capturar un volcado de hilo:
kill -3 17264
This way the signal-receiving Java process will print the thread dump on the standard output.
If we run the Java process with the following combination of tuning flags, then it will also redirect the thread dump to the given file:
-XX:+UnlockDiagnosticVMOptions -XX:+LogVMOutput -XX:LogFile=~/jvm.log
Now if we send the -3 signal, in addition to the standard output, the dump will be available at ~/jvm.log file.
3.2. Ctrl + Break (Windows)
In Windows operating systems, we can capture a thread dump using the CTRL and Break key combination. To take a thread dump, navigate to the console used to launch the Java application and press CTRL and Break keys together.
It's worth noting that, on some keyboards, the Break key is not available. Therefore, in such cases, a thread dump can be captured using CTRL, SHIFT, and Pause keys together.
Both of these commands print the thread dump to the console.
4. Programmatically Using ThreadMxBean
The last approach we will discuss in the article is using JMX. We'll use ThreadMxBean to capture the thread dump. Let's see it in code:
private static String threadDump(boolean lockedMonitors, boolean lockedSynchronizers) { StringBuffer threadDump = new StringBuffer(System.lineSeparator()); ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); for(ThreadInfo threadInfo : threadMXBean.dumpAllThreads(lockedMonitors, lockedSynchronizers)) { threadDump.append(threadInfo.toString()); } return threadDump.toString(); }
In the above program, we are performing several steps:
- At first, an empty StringBuffer is initialized to hold the stack information of each thread.
- We then use the ManagementFactory class to get the instance of ThreadMxBean. A ManagementFactory is a factory class for getting managed beans for the Java platform. In addition, a ThreadMxBean is the management interface for the thread system of the JVM.
- Setting lockedMonitors and lockedSynchronizers values to true indicates to capture the ownable synchronizers and all locked monitors in the thread dump.
5. Conclusion
In this article, we've shown multiple ways to capture a thread dump.
At first, we discussed various JDK Utilities and then the command-line alternatives. In the last section, we concluded with the programmatic approach using JMX.
Como siempre, el código fuente completo del ejemplo está disponible en GitHub.