Como administrador de sistemas, a veces me enfrento a situaciones en las que un programa se comporta de manera anormal, sin crear errores ni mensajes de error sin sentido.
En el pasado, antes de que llegara Java, había dos contramedidas:
Si nada más ayuda - RTFM ;-)
Si incluso 1. no ayuda, rastree las llamadas al sistema y vea qué está sucediendo
Normalmente lo uso strace -fpara esta tarea con Linux (otros sistemas operativos tienen herramientas de rastreo similares). Ahora, si bien esto generalmente funciona bien para cualquier programa antiguo, la traza se vuelve muy borrosa cuando se hace lo mismo en un proceso de Java . Hay tantas llamadas al sistema que aparentemente no están relacionadas con ninguna acción real, que es terrible buscar en ese basurero.
¿Hay mejores formas de hacerlo (si el código fuente no está disponible)?
Como mencionó ckhan, jstackes excelente porque proporciona el seguimiento completo de la pila de todos los subprocesos activos en la JVM. Lo mismo se puede obtener en stderr de la JVM usando SIGQUIT.
Otra herramienta útil es la jmapque puede obtener un volcado de pila del proceso JVM utilizando el PID del proceso:
jmap -dump:file=/tmp/heap.hprof $PID
Este volcado de visualvmalmacenamiento dinámico se puede cargar en herramientas como (que ahora forma parte de la instalación estándar de Oracle java sdk, llamada jvisualvm). Además, VisualVM puede conectarse a la JVM en ejecución y mostrar información sobre la JVM, incluida la visualización de gráficos de uso interno de CPU, recuento de subprocesos y uso de almacenamiento dinámico, ideal para rastrear fugas.
Otra herramienta, jstatpuede recopilar estadísticas de recolección de basura para la JVM durante un período de tiempo muy similar a vmstat cuando se ejecuta con un argumento numérico (por ejemplo vmstat 3).
Finalmente, es posible usar un Agente Java para impulsar la instrumentación en todos los métodos de todos los objetos en el momento de la carga. La biblioteca javassistpuede ayudar a hacer esto muy fácil de hacer. Por lo tanto, es factible agregar su propio rastreo. La parte difícil con eso sería encontrar una manera de obtener resultados de rastreo solo cuando lo deseara y no todo el tiempo, lo que probablemente ralentizaría la JVM. Hay un programa llamado dtraceque funciona de esta manera. Lo intenté, pero no tuve mucho éxito. Tenga en cuenta que los agentes no pueden instrumentar todas las clases porque las necesarias para arrancar la JVM se cargan antes de que el agente pueda instrumentar, y luego es demasiado tarde para agregar instrumentación a esas clases.
Mi sugerencia : comience con VisualVM y vea si eso le dice lo que necesita saber, ya que puede mostrar los hilos actuales y las estadísticas importantes para la JVM.
Por cierto, esta es una pregunta increíble; Espero que más personas agreguen respuestas con otras ideas. Cuando le pregunté a la gente que trabajaba con Java durante muchos años sobre el rastreo, me dieron miradas en blanco. Quizás simplemente no conocen la genialidad de strace.
ceniza
10
En el mismo sentido, al depurar programas que han salido mal en un sistema Linux, puede usar herramientas similares para depurar ejecutando JVM en su sistema.
Herramienta # 1 - jvmtop
De manera similar top, puede usar jvmtop para ver qué clases están dentro de las JVM en ejecución en su sistema. Una vez instalado, lo invocas así:
$ jvmtop.sh
Su salida tiene un estilo similar al de la herramienta top:
JvmTop 0.8.0 alpha amd64 8 cpus, Linux 2.6.32-27, load avg 0.12
http://code.google.com/p/jvmtop
PID MAIN-CLASS HPCUR HPMAX NHCUR NHMAX CPU GC VM USERNAME #T DL
3370 rapperSimpleApp 165m 455m 109m 176m 0.12% 0.00% S6U37 web 21
11272 ver.resin.Resin [ERROR: Could not attach to VM]
27338 WatchdogManager 11m 28m 23m 130m 0.00% 0.00% S6U37 web 31
19187 m.jvmtop.JvmTop 20m 3544m 13m 130m 0.93% 0.47% S6U37 web 20
16733 artup.Bootstrap 159m 455m 166m 304m 0.12% 0.00% S6U37 web 46
Herramienta # 2 - jvmmonitor
Otra alternativa es usar jvmmonitor . JVM Monitor es un generador de perfiles Java integrado con Eclipse para monitorear el uso de CPU, subprocesos y memoria de aplicaciones Java. Puede usarlo para buscar automáticamente JVM en ejecución en el host local o puede conectarse a JVM remotas utilizando un puerto @ host.
Herramienta # 3 - visualvm
visualvm es probablemente "la herramienta" a la que recurrir cuando se depuran problemas con la JVM. Su conjunto de características es bastante profundo y puede obtener una mirada muy profunda a las entrañas.
Perfile el rendimiento de la aplicación o analice la asignación de memoria:
Considere jstack. No es una coincidencia para strace, más bien un pstackanálogo, pero al menos le dará una imagen de una instantánea a tiempo. Podría unirlos para obtener un rastro tosco si fuera necesario.
Si está utilizando RHEL OpenJDK (o similar, el punto es que no es JDK de Oracle), puede usar SystemTap para eso.
Algunas sondas se habilitan mediante el uso de las opciones de línea de comandos de Java -XX:+DTraceMethodProbes, -XX:+DTraceAllocProbes, -XX:+DTraceMonitorProbes. Tenga en cuenta que habilitar estas sondas afectará significativamente el rendimiento del programa.
También puede usar jstack()para obtener la pila Java del proceso, pero solo funcionará si inicia SystemTap antes de JVM.
Tenga en cuenta que SystemTap rastreará todos los métodos. Tampoco puede obtener argumentos del método. Otra opción es utilizar las capacidades propias de rastreo de JVM, que se llama JVMTI. Una de las implementaciones de JVMTI más famosas es BTrace .
Se recomienda probar Jackplay , que es una herramienta de rastreo JVM que le permite rastrear la entrada y salida de métodos sin cambio de código o redistribución.
En el mismo sentido, al depurar programas que han salido mal en un sistema Linux, puede usar herramientas similares para depurar ejecutando JVM en su sistema.
Herramienta # 1 - jvmtop
De manera similar
top
, puede usar jvmtop para ver qué clases están dentro de las JVM en ejecución en su sistema. Una vez instalado, lo invocas así:Su salida tiene un estilo similar al de la herramienta
top
:Herramienta # 2 - jvmmonitor
Otra alternativa es usar jvmmonitor . JVM Monitor es un generador de perfiles Java integrado con Eclipse para monitorear el uso de CPU, subprocesos y memoria de aplicaciones Java. Puede usarlo para buscar automáticamente JVM en ejecución en el host local o puede conectarse a JVM remotas utilizando un puerto @ host.
Herramienta # 3 - visualvm
visualvm es probablemente "la herramienta" a la que recurrir cuando se depuran problemas con la JVM. Su conjunto de características es bastante profundo y puede obtener una mirada muy profunda a las entrañas.
Perfile el rendimiento de la aplicación o analice la asignación de memoria:
Tomar y mostrar volcados de subprocesos:
Referencias
fuente
Considere
jstack
. No es una coincidencia parastrace
, más bien unpstack
análogo, pero al menos le dará una imagen de una instantánea a tiempo. Podría unirlos para obtener un rastro tosco si fuera necesario.Consulte también las sugerencias en este artículo de SO: /programming/1025681/call-trace-in-java
fuente
Si está utilizando RHEL OpenJDK (o similar, el punto es que no es JDK de Oracle), puede usar SystemTap para eso.
Algunas sondas se habilitan mediante el uso de las opciones de línea de comandos de Java
-XX:+DTraceMethodProbes
,-XX:+DTraceAllocProbes
,-XX:+DTraceMonitorProbes
. Tenga en cuenta que habilitar estas sondas afectará significativamente el rendimiento del programa.Aquí hay un ejemplo de Script SystemTap:
También puede usar
jstack()
para obtener la pila Java del proceso, pero solo funcionará si inicia SystemTap antes de JVM.Tenga en cuenta que SystemTap rastreará todos los métodos. Tampoco puede obtener argumentos del método. Otra opción es utilizar las capacidades propias de rastreo de JVM, que se llama JVMTI. Una de las implementaciones de JVMTI más famosas es BTrace .
fuente
Se recomienda probar Jackplay , que es una herramienta de rastreo JVM que le permite rastrear la entrada y salida de métodos sin cambio de código o redistribución.
fuente