Tengo una aplicación Java que ejecuto desde una consola que a su vez ejecuta otro proceso Java. Quiero obtener un volcado de hebra / montón de ese proceso secundario.
En Unix, podría hacer un kill -3 <pid>
pero en Windows AFAIK la única forma de obtener un volcado de subprocesos es Ctrl-Break en la consola. Pero eso solo me da el vuelco del proceso padre, no el hijo.
¿Hay otra forma de obtener ese volcado de montón?
java
jvm
heap-dump
thread-dump
Kasun Siyambalapitiya
fuente
fuente
Respuestas:
Puede usar
jmap
para obtener un volcado de cualquier proceso en ejecución, suponiendo que conozca elpid
.Utilice el Administrador de tareas o el Monitor de recursos para obtener el
pid
. Luegopara obtener el montón para ese proceso.
fuente
Estás confundiendo dos volcados de Java diferentes.
kill -3
genera un volcado de subprocesos, no un volcado de almacenamiento dinámico.Para realizar un volcado de subprocesos en Windows, CTRL+ BREAKsi su JVM es el proceso en primer plano es la forma más sencilla. Si tiene un shell similar a Unix en Windows como Cygwin o MobaXterm, puede usarlo
kill -3 {pid}
como puede hacerlo en Unix.Para realizar un volcado de subprocesos en Unix, CTRL+ Csi su JVM es el proceso en primer plano o
kill -3 {pid}
funcionará siempre que obtenga el PID correcto para la JVM.Con cualquier plataforma, Java viene con varias utilidades que pueden ayudar. Para volcados de hilo,
jstack {pid}
es su mejor apuesta. http://docs.oracle.com/javase/1.5.0/docs/tooldocs/share/jstack.htmlSolo para terminar la pregunta del volcado: los volcados del montón no se usan comúnmente porque son difíciles de interpretar. Sin embargo, tienen mucha información útil si sabes dónde / cómo mirarlos. El uso más común es localizar pérdidas de memoria. Es una buena práctica establecer el
-D
en la línea de comandos de Java para que el volcado del montón se genere automáticamente en un OutOfMemoryError,-XX:+HeapDumpOnOutOfMemoryError
pero también puede activar manualmente un volcado del montón. La forma más común es usar la utilidad javajmap
.NOTA: esta utilidad no está disponible en todas las plataformas. A partir de JDK 1.6,
jmap
está disponible en Windows.Un ejemplo de línea de comando sería algo así
El resultado "myheap.bin" no es legible por humanos (para la mayoría de nosotros), y necesitará una herramienta para analizarlo. Mi preferencia es MAT. http://www.eclipse.org/mat/
fuente
Creo que la mejor manera de crear un archivo .hprof en el proceso de Linux es con el comando jmap . Por ejemplo:
jmap -dump:format=b,file=filename.hprof {PID}
fuente
Además de usar el jconsole / visualvm mencionado, puede usarlo
jstack -l <vm-id>
en otra ventana de línea de comando y capturar esa salida.El <vm-id> se puede encontrar usando el administrador de tareas (es la identificación del proceso en Windows y Unix), o usando
jps
.Tanto
jstack
yjps
se incluirá en la versión de Sun JDK 6 y superior.fuente
Recomiendo Java VisualVM distribuido con JDK (jvisualvm.exe). Se puede conectar dinámicamente y acceder a los subprocesos y al montón. He encontrado en invaluable para algunos problemas.
fuente
Si está en server-jre 8 y superior, puede usar esto:
fuente
Pruebe una de las siguientes opciones.
Para JVM de 32 bits:
Para JVM de 64 bits (citando explícitamente):
Para JVM de 64 bits con algoritmo G1GC en parámetros VM (solo el montón de objetos vivos se genera con el algoritmo G1GC):
Pregunta SE relacionada: error de volcado del montón de Java con el comando jmap: EOF prematuro
Echa un vistazo a varias opciones de
jmap
en este artículofuente
Si desea un heapdump sin memoria, puede iniciar Java con la opción
-XX:-HeapDumpOnOutOfMemoryError
cf Página de referencia de opciones de JVM
fuente
Puede ejecutar
jconsole
(incluido con el SDK de Java 6) y luego conectarse a su aplicación Java. Le mostrará cada subproceso en ejecución y su seguimiento de pila.fuente
Puedes enviarlo
kill -3 <pid>
desde Cygwin. Debe usar lasps
opciones de Cygwin para buscar procesos de Windows y luego enviar la señal a ese proceso.fuente
Debe redirigir la salida del segundo ejecutable de Java a algún archivo. Luego, use SendSignal para enviar "-3" a su segundo proceso.
fuente
Si está utilizando JDK 1.6 o superior, puede usar el
jmap
comando para realizar un volcado dinámico de un proceso Java, la condición es que debe conocer ProcessID.Si está en una máquina con Windows, puede usar el Administrador de tareas para obtener PID. Para la máquina Linux, puede usar variedades de comandos como
ps -A | grep java
onetstat -tupln | grep java
otop | grep java
, depende de su aplicación.Entonces puede usar el comando como
jmap -dump:format=b,file=sample_heap_dump.hprof 1234
donde 1234 es PID.Existen diversas herramientas disponibles para interpretar el archivo hprof. Recomendaré la herramienta visualvm de Oracle, que es fácil de usar.
fuente
Si no puede (o no quiere) usar la consola / terminal por alguna razón, hay una solución alternativa. Puede hacer que la aplicación Java imprima el volcado de subprocesos por usted. El código que recopila Stack Trace es razonablemente simple y se puede adjuntar a un botón o una interfaz web.
Este método devolverá una cadena que se ve así:
Para aquellos interesados en una versión Java 8 con transmisiones, el código es aún más compacto:
Puede probar fácilmente este código con:
fuente
La siguiente secuencia de comandos utiliza PsExec para conectarse a otra sesión de Windows, por lo que funciona incluso cuando se conecta a través del Servicio de escritorio remoto.
Escribí un pequeño script por lotes para Java 8 (usando
PsExec
yjcmd
) llamadojvmdump.bat
, que volca los hilos, el montón, las propiedades del sistema y los argumentos JVM.Debe ejecutarse en la misma sesión de Windows del usuario que inició la JVM, por lo que si se conecta a través de Escritorio remoto, es posible que deba iniciar un símbolo del sistema
Session 0
y ejecutarlo desde allí. p.ejEsto le indicará (haga clic en el icono de la barra de tareas en la parte inferior)
View the message
en la sesión interactiva, que lo llevará a la nueva consola en la otra sesión desde la que puede ejecutar eljvmdump.bat
script.fuente
¿Cómo obtener la identificación del proceso de la aplicación Java?
Ejecute el comando 'jcmd' para obtener el id de proceso de las aplicaciones java.
¿Cómo obtener el volcado de subprocesos?
jcmd PID Thread.print> thread.dump
Enlace de referencia
Incluso puede usar jstack para obtener volcado de hilo (jstack PID> thread.dump). Enlace de referencia
¿Cómo obtener el volcado del montón?
Use la herramienta jmap para obtener el volcado del montón. jmap -F -dump: live, format = b, file = heap.bin PID
PID significa id de proceso de la aplicación. Enlace de referencia
fuente
Tal vez jcmd ?
La utilidad Jcmd se utiliza para enviar solicitudes de comandos de diagnóstico a la JVM, donde estas solicitudes son útiles para controlar las grabaciones de vuelo de Java, solucionar problemas y diagnosticar aplicaciones JVM y Java.
La herramienta jcmd se introdujo con Java 7 de Oracle y es particularmente útil para solucionar problemas con aplicaciones JVM al usarla para identificar los ID de los procesos Java (similares a jps), adquirir volcados de montón (similares a jmap), adquirir volcados de subprocesos (similares a jstack ), ver las características de la máquina virtual, como las propiedades del sistema y los indicadores de línea de comandos (similar a jinfo), y adquirir estadísticas de recolección de basura (similar a jstat). La herramienta jcmd ha sido llamada "una navaja suiza para investigar y resolver problemas con su aplicación JVM" y una "gema oculta".
Este es el proceso que deberá utilizar para invocar
jcmd
:jcmd <pid> GC.heap_dump <file-path>
Compruébelo para obtener más información sobre cómo realizar un volcado de almacenamiento dinámico de Java .
fuente
Seguimiento visualvm:
Si "no puede conectarse" a su JVM en ejecución desde jvisualvm porque no lo inició con los argumentos JVM correctos (y está en el cuadro remoto), ejecute
jstatd
en el cuadro remoto y, suponiendo que tenga una conexión directa, agregue como "host remoto" en visualvm, haga doble clic en el nombre del host, y todas las demás JVM en ese cuadro aparecerán mágicamente en visualvm.Si no tiene "conexión directa" a los puertos en ese cuadro, también puede hacerlo a través de un proxy .
Una vez que pueda ver el proceso que desea, profundice en él en jvisualvm y use la pestaña del monitor -> botón "heapdump".
fuente
El siguiente código de Java se utiliza para obtener el volcado del montón de un proceso Java al proporcionar PID. El programa usa una conexión JMX remota para volcar el montón. Puede ser útil para alguien.
}
fuente
Para realizar el volcado de hebras / volcado de montón de un proceso Java secundario en Windows, debe identificar el Id. Del proceso secundario como primer paso.
Al emitir el comando: jps , podrá obtener todos los ID de proceso de Java que se ejecutan en su máquina Windows. De esta lista, debe seleccionar el ID del proceso secundario. Una vez que tenga el ID de proceso hijo, hay varias opciones para capturar volcados de hebras y volcados de almacenamiento dinámico.
Capturando volcados de hilos:
Hay 8 opciones para capturar volcados de subprocesos:
Los detalles sobre cada opción se pueden encontrar en este artículo . Una vez que haya capturado los volcados de subprocesos, puede usar herramientas como fastThread , Samuraito analiza los volcados de subprocesos.
Capturando volcados del montón:
Hay 7 opciones para capturar volcados de almacenamiento dinámico:
jmap
-XX: + HeapDumpOnOutOfMemoryError
jcmd
JVisualVM
JMX
Enfoque programático
Consolas administrativas
Los detalles sobre cada opción se pueden encontrar en este artículo . Una vez que haya capturado el volcado de almacenamiento dinámico, puede usar herramientas como la herramienta de Análisis de memoria de Eclipse , HeapHero para analizar los volcados de almacenamiento dinámico capturados.
fuente
En un Oracle JDK, tenemos un comando llamado jmap (disponible en la carpeta bin de Java Home). El uso del comando viene de la siguiente manera
Ejemplo: jmap -dump: live, format = b, file = heap.bin (pid)
fuente