Herramienta para analizar grandes volcados de pila de Java

80

Tengo un volcado de pila HotSpot JVM que me gustaría analizar. Se ejecutó la máquina virtual -Xmx31gy el archivo de volcado de pila tiene 48 GB de tamaño.

  • Ni siquiera lo intentaré jhat, ya que requiere aproximadamente cinco veces la memoria del montón (eso sería 240 GB en mi caso) y es terriblemente lento.
  • Eclipse MAT se bloquea ArrayIndexOutOfBoundsExceptiondespués de analizar el volcado de pila durante varias horas.

¿Qué otras herramientas están disponibles para esa tarea? Lo mejor sería un conjunto de herramientas de línea de comandos, que consta de un programa que transforma el volcado de pila en estructuras de datos eficientes para el análisis, combinado con varias otras herramientas que funcionan con datos preestructurados.

Roland Illig
fuente
¿Está seguro de que el volcado no está dañado y de que está utilizando una versión más reciente de los archivos JAR DTFJ? Las ArrayIndexOutOfBoundsExceptioncaracterísticas en al menos dos errores . Lo digo porque no ha informado un OOME al ejecutar MAT, que tiene una solución diferente .
Vineet Reynolds
jhat usa heapMap para almacenar los objetos leídos, que crece exponencialmente con la cantidad de objetos almacenados en heap. Una opción es cambiar los decl's de heapMap a TreeMap, y ejecutar el tamaño del montón de jhat al menos tan grande como su proceso.
codeDr

Respuestas:

80

Normalmente, lo que uso se ParseHeapDump.shincluye dentro de Eclipse Memory Analyzer y se describe aquí , y lo hago en uno de nuestros servidores más reforzados (descargue y copie sobre la distribución de Linux .zip, descomprímalo allí). El script de shell necesita menos recursos que analizar el montón desde la GUI, además, puede ejecutarlo en su servidor robusto con más recursos (puede asignar más recursos agregando algo como -vmargs -Xmx40g -XX:-UseGCOverheadLimital final de la última línea del script. Por ejemplo, la última línea de ese archivo podría verse así después de la modificación

./MemoryAnalyzer -consolelog -application org.eclipse.mat.api.parse "$@" -vmargs -Xmx40g -XX:-UseGCOverheadLimit

Ejecutarlo como ./path/to/ParseHeapDump.sh ../today_heap_dump/jvm.hprof

Después de que tenga éxito, crea varios archivos de "índice" junto al archivo .hprof.

Después de crear los índices, trato de generar informes a partir de eso y enviar esos informes a mis máquinas locales y tratar de ver si puedo encontrar al culpable solo por eso (no solo los informes, no los índices). Aquí hay un tutorial sobre cómo crear los informes .

Informe de ejemplo:

./ParseHeapDump.sh ../today_heap_dump/jvm.hprof org.eclipse.mat.api:suspects

Otras opciones de informe:

org.eclipse.mat.api:overview y org.eclipse.mat.api:top_components

Si esos informes no son suficientes y necesito un poco más de investigación (es decir, digamos a través de oql), hago un scp de los índices y el archivo hprof en mi máquina local y luego abro el volcado de pila (con los índices en el mismo directorio el volcado de pila) con mi GUI Eclipse MAT. A partir de ahí, no necesita demasiada memoria para ejecutarse.

EDITAR: solo me gustó agregar dos notas:

  • Hasta donde yo sé, solo la generación de índices es la parte de memoria intensiva de Eclipse MAT. Una vez que tenga los índices, la mayor parte de su procesamiento de Eclipse MAT no necesitaría tanta memoria.
  • Hacer esto en un script de shell significa que puedo hacerlo en un servidor sin cabeza (y normalmente lo hago también en un servidor sin cabeza, porque normalmente son los más poderosos). Y si tiene un servidor que puede generar un volcado de montón de ese tamaño, lo más probable es que tenga otro servidor que pueda procesar tanto volcado de montón.
Franz See
fuente
4
Nota importante: ParseHeapDump.shestá empaquetado solo con la versión de Linux, no con la versión de OSX - eclipse.org/mat/downloads.php
Christopher
Cuando intento esto (ssh para golpear en una caja de Linux), falla inmediatamente con "No se puede inicializar GTK +". Entonces, parece que (la versión actual, 2016-04-15) todavía cree que está hablando con una interfaz de usuario (?).
Charles Roth
2
Hmm, las versiones más nuevas de ParseHeapDump.sh quieren ejecutar ./MemoryAnalyzer directamente. Estoy experimentando con ejecutar el lanzador directamente con java, hasta ahora parece estar funcionando, por ejemplo, java -Xmx16g -Xms16g -jar plugins / org.eclipse.equinox.launcher_1.3.100.v20150511-1540.jar -consoleLog -consolelog -application org.eclipse.mat.api.parse "$ @"
Charles Roth
Parece que puede usarlo en OS X descargando las versiones de Linux y OSX, luego copie ParseHeapDump.sh en el mismo directorio que su archivo MemoryAnalyze (en mi caso, ~ / Downloads / mat.app / Contents / MacOS) y modifique y ejecutarlo allí. O ejecútelo en algún servidor remoto, por supuesto, a través de SSH :)
rogerdpack
Se abrió un volcado de almacenamiento dinámico de 2GB con la GUI de Eclipse Memory Analyzer usando no más de 500MB de memoria. Los archivos de índice se crearon sobre la marcha al abrir el archivo (se tomó ~ 30 segundos). Quizás mejoraron la herramienta. Es más conveniente que copiar archivos grandes de un lado a otro, si realmente funciona de esta manera. La pequeña huella de memoria, incluso sin ninguna utilidad de consola, es una gran ventaja para mí. Pero para ser honesto, no lo intenté con volcados realmente grandes (más de 50 GB). Es muy interesante la cantidad de memoria que se requiere para abrir y analizar volcados tan grandes con esta herramienta.
Ruslan Stelmachenko
6

La respuesta aceptada a esta pregunta relacionada debería proporcionarle un buen comienzo (utiliza histogramas de jmap en vivo en lugar de volcados de pila):

Método para encontrar pérdidas de memoria en grandes volcados de almacenamiento dinámico de Java

La mayoría de los otros analizadores de montón (yo uso IBM http://www.alphaworks.ibm.com/tech/heapanalyzer ) requieren al menos un porcentaje de RAM más que el montón si espera una buena herramienta GUI.

Aparte de eso, muchos desarrolladores utilizan enfoques alternativos, como el análisis de pila en vivo para tener una idea de lo que está sucediendo.

Aunque debo preguntarme por qué sus montones son tan grandes. El efecto sobre la asignación y la recolección de basura debe ser masivo. Apuesto a que un gran porcentaje de lo que hay en su montón debería almacenarse en una base de datos / un caché persistente, etc.

Miguel
fuente
5

Sugiero probar YourKit. Por lo general, necesita un poco menos de memoria que el tamaño del volcado de pila (lo indexa y usa esa información para recuperar lo que desea)

Peter Lawrey
fuente
4

Algunas opciones más:

Esta persona http://blog.ragozin.info/2015/02/programatic-heapdump-analysis.html

escribió un analizador de montón Netbeans personalizado que solo expone una interfaz de "estilo de consulta" a través del archivo de volcado de montón, en lugar de cargar el archivo en la memoria.

https://github.com/aragozin/jvm-tools/tree/master/hprof-heap

Aunque no sé si "su lenguaje de consulta" es mejor que el eclipse OQL mencionado en la respuesta aceptada aquí.

También se dice que JProfiler 8.1 ($ 499 por licencia de usuario) puede atravesar grandes montones sin gastar mucho dinero.

Rogerdpack
fuente
En realidad, funciona en un gran vertedero, a diferencia de github.com/on-site/fasthat . ¡Agradable!
Jesse Glick
4

Primer paso: aumente la cantidad de RAM que está asignando a MAT. De forma predeterminada, no es mucho y no puede abrir archivos grandes.

En caso de utilizar MAT en MAC (OSX), tendrá el archivo MemoryAnalyzer.ini en MemoryAnalyzer.app/Contents/MacOS. No me funcionó hacer ajustes en ese archivo y hacer que se "tomaran". En su lugar, puede crear un comando de inicio / script de shell modificado basado en el contenido de este archivo y ejecutarlo desde ese directorio. En mi caso, quería un montón de 20 GB:

./MemoryAnalyzer -vmargs -Xmx20g --XX:-UseGCOverheadLimit ... other params desired

Simplemente ejecute este comando / script desde el directorio Contenido / MacOS a través de la terminal, para iniciar la GUI con más RAM disponible.

Michael Shvets
fuente
Gracias. DLd la utilidad hoy. Intenté ejecutar con 2x clic y dio un error. Miró el registro, no pudo crear un archivo de datos y dijo que usaba un interruptor. Abrió el paquete .app y encontró MemoryAnalyzer.ini en la carpeta Eclipse \, no en \ MacOS. ¡Ah-ja! Así que extraje todos los archivos localmente e hice lo que sugirió. Creé un archivo .sh en \ MacOS y moví los comandos en Eclipse \ MemoryAnalyzer.ini como una sola línea plana. Archivo guardado. Ejecuté el archivo .sh de MacOS \ en la línea de comando y listo, funcionó.
Matt Campbell
2

Una herramienta no tan conocida: http://dr-brenschede.de/bheapsampler/ funciona bien para montones grandes. Funciona mediante muestreo, por lo que no tiene que leerlo todo, aunque es un poco meticuloso.

Ashwin Jayaprakash
fuente
Desafortunadamente, dice "problema común: quedarse sin memoria: aumentar el -Xmx a 2/3 del tamaño de volcado", pero supongo que si tiene suficiente RAM o puede ejecutarlo en un servidor con suficiente, eso podría ser suficiente, gracias !
rogerdpack
2

La última versión de instantánea de Eclipse Memory Analyzer tiene una función para descartar aleatoriamente un cierto porcentaje de objetos para reducir el consumo de memoria y permitir el análisis de los objetos restantes. Consulte el error 563960 y la compilación de instantáneas nocturnas para probar esta función antes de que se incluya en la próxima versión de MAT.

usuario13762112
fuente
1

Esta no es una solución de línea de comandos, sin embargo, me gustan las herramientas:

Copie el volcado de pila en un servidor lo suficientemente grande como para alojarlo. Es muy posible que se pueda utilizar el servidor original.

Ingrese al servidor vía ssh -Xpara ejecutar la herramienta gráfica de forma remota y use jvisualvmdesde el directorio binario de Java para cargar el .hprofarchivo del volcado de pila.

La herramienta no carga el volcado de pila completo en la memoria a la vez, sino que carga las partes cuando son necesarias. Por supuesto, si mira lo suficiente en el archivo, la memoria requerida finalmente alcanzará el tamaño del volcado de pila.

kap
fuente
0

Intente usar jprofiler, funciona bien para analizar archivos .hprof grandes, lo he intentado con un tamaño de archivo de alrededor de 22 GB.

https://www.ej-technologies.com/products/jprofiler/overview.html
Selvam M
fuente
0

Encontré una herramienta interesante llamada JXray. Proporciona una licencia de prueba de evaluación limitada. Lo encontré muy útil para encontrar fugas de memoria. Puede intentarlo.

Sankar Natarajan
fuente