2011-08-31 13 views
53

Tengo un volcado de heap HotSpot JVM que me gustaría analizar. La VM se ejecutó con -Xmx31g y el archivo de volcado de almacenamiento dinámico es de 48 GB de tamaño.Herramienta para analizar grandes volcados de heap Java

  • ni siquiera voy a tratar jhat, ya que requiere alrededor de cinco veces la memoria del montón (que sería de 240 GB en mi caso) y es terriblemente lento.
  • Eclipse MAT se bloquea con un ArrayIndexOutOfBoundsException después de analizar el volcado del montón durante varias horas.

¿Qué otras herramientas hay disponibles para esa tarea? Un conjunto de herramientas de línea de comandos sería lo mejor, que consistiría en un programa que transforma el volcado de almacenamiento dinámico en estructuras de datos eficientes para el análisis, combinado con otras herramientas que trabajan en los datos preestructurados.

+0

¿Estás seguro de que el volcado no está dañado y de que estás utilizando una versión más reciente de los JAR DTFJ? Las características 'ArrayIndexOutOfBoundsException' en atleast [two] (https://bugs.eclipse.org/bugs/show_bug.cgi?id=294311) [bugs] (https://bugs.eclipse.org/bugs/show_bug.cgi ? id = 307530). Estoy diciendo esto porque no has informado [un OOME al ejecutar MAT, que tiene una solución diferente] (http://wiki.eclipse.org/MemoryAnalyzer/FAQ#Out_of_Memory_Error_while_Running_the_Memory_Analyzer). –

+0

jhat usa heapMap para almacenar los objetos leídos, que crece exponencialmente con la cantidad de objetos almacenados en el montón. Una opción es cambiar los decl's de heapMap a TreeMap, y ejecutar el tamaño de almacenamiento dinámico de jhat al menos tan grande como su proceso. – codeDr

Respuesta

40

Normalmente, lo que yo uso se incluyen dentro ParseHeapDump.shEclipse Memory Analyzer y se describen here, y yo que en una sola nuestros servidores más reforzados (descargue y copie sobre la distribución linux .zip, descomprima allí). El script de shell necesita menos recursos que analizar el almacenamiento dinámico desde la GUI, además puede ejecutarlo en su gran servidor con más recursos (puede asignar más recursos agregando algo como -vmargs -Xmx40g -XX:-UseGCOverheadLimit al final de la última línea del script. Para ejemplo, la última línea del archivo que podría tener este aspecto después de la modificación

./MemoryAnalyzer -consolelog -application org.eclipse.mat.api.parse "[email protected]" -vmargs -Xmx40g -XX:-UseGCOverheadLimit 

Ejecutar como si fuera ./path/to/ParseHeapDump.sh ../today_heap_dump/jvm.hprof

después de eso tiene éxito, se crea una serie de archivos "índice" junto al archivo .hprof.

Después de crear los índices, trato de generar puntúe informes de eso y envíe esos informes a mis máquinas locales y trate de ver si puedo encontrar al culpable solo con eso (no solo los informes, no los índices). Aquí hay un tutorial en creating the reports.

ejemplo de informe:

./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 si necesito un poco más de excavación (es decir,digamos a través de oql), selecciono los índices y el archivo hprof en mi máquina local, y luego abro el volcado de heap (con los índices en el mismo directorio que el volcado de heap) con mi GUI de Eclipse MAT. A partir de ahí, no necesita demasiada memoria para funcionar.

EDIT: yo sólo le gusta añadir dos notas:

  • Por lo que yo sé, sólo la generación de los índices es la parte intensiva de memoria de Eclipse MAT. Después de tener 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 en un servidor sin cabeza, porque normalmente son los más poderosos). Y si tiene un servidor que puede generar un volcado dinámico de ese tamaño, lo más probable es que tenga otro servidor que pueda procesar esa cantidad de volcado de almacenamiento dinámico.
+2

Nota importante: 'ParseHeapDump.sh' está empaquetado con la versión de Linux solamente, no con la versión de OSX - http://www.eclipse.org/mat/downloads.php – Christopher

+0

Cuando intento esto (ssh'd bash en un linux box), falla inmediatamente con "Incapaz de inicializar GTK +". Entonces parece que (la versión actual, 2016-04-15) todavía cree que está hablando con una IU (?). –

+2

Hmm, las versiones más nuevas de ParseHeapDump.sh quieren ejecutar ./MemoryAnalyzer directamente. Estoy experimentando con ejecutar el lanzador directamente con java, hasta el momento parece estar funcionando, p. java-jar -Xmx16g -Xms16g plugins/org.eclipse.equinox.launcher_1.3.100.v20150511-1540.jar -consoleLog -consolelog -aplicación org.eclipse.mat.api.parse "$ @" –

5

La respuesta aceptada a esta pregunta relacionada debería proporcionar un buen punto de partida para usted (utiliza jmap vivo histogramas en lugar de vuelcos de almacenamiento dinámico):

Method for finding memory leak in large Java heap dumps

mayoría de los analizadores otro montón (que utilizan IBM http://www.alphaworks.ibm.com/tech/heapanalyzer) requieren por lo al menos un porcentaje de RAM más que el montón si está esperando una buena herramienta de 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 preguntar por qué sus montones son tan grandes? El efecto sobre la asignación y la recolección de basura debe ser masivo. Apostaría un gran porcentaje de lo que está en su montón en realidad debería ser almacenada en una base de datos/una persistente caché, etc, etc

3

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

2

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

+0

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

1

En caso de utilizar MAT en MAC (OSX), tendrá el archivo MemoryAnalyzer.ini en MemoryAnalyzer.app/Contents/MacOS. No estaba funcionando para mí. Puede crear un comando de inicio/shell shell modificado en función del contenido de este archivo y ejecutarlo desde ese directorio. En mi caso yo quería 20 GB montón:

./MemoryAnalyzer -startup ../../../plugins/org.eclipse.equinox.launcher_1.3.100.v20150511-1540.jar --launcher.library ../../../plugins/org.eclipse.equinox.launcher.cocoa.macosx.x86_64_1.1.300.v20150602-1417 -vmargs -Xmx20g --XX:-UseGCOverheadLimit -Dorg.eclipse.swt.internal.carbon.smallFonts -XstartOnFirstThread 

Sólo tiene que ejecutar este comando/script desde el directorio Contenido/MacOS a través del terminal, para iniciar la interfaz gráfica de usuario con más memoria RAM disponible.

3

algunas opciones más:

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

escribió un analizador de encargo Netbeans almacenamiento dinámico que simplemente expone una interfaz estilo "consulta" a través del archivo de volcado de pila, en lugar de realmente 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 de NCO se menciona en la respuesta aceptada aquí.

JProfiler 8.1 ($ 499 para licencia de usuario) también es said para poder recorrer grandes montones sin usar mucho dinero.

+0

Actualmente funciona en un gran vertedero, a diferencia de https://github.com/on-site/fasthat. ¡Bonito! –

Cuestiones relacionadas