¿Cómo tomar volcados de almacenamiento dinámico de Java de manera confiable?

9

Mi equipo se encuentra con dificultades cuando intenta realizar buenos volcados de memoria activados por OutOfMemoryErrors. Por razones específicas, actualmente estamos realizando los volcados con jmap llamado desde un script bash en lugar de usar el indicador HeapDumpOnOutOfMemoryError. Estamos utilizando una JVM 1.6 de 64 bits con un tamaño de almacenamiento dinámico de alrededor de 3 GB. Nuestros volcados de pila fallan el 90% del tiempo (estimación aproximada).

¿Hay algo que podamos hacer para mejorar nuestras probabilidades de obtener un volcado de almacenamiento dinámico que podamos usar para solucionar problemas de memoria? He leído que jmap tenía problemas importantes en Java 1.4, pero que esos problemas deberían abordarse principalmente ahora.

karlcyr
fuente
44
Nomino esta pregunta para "el sonido más desagradable involuntario".
phoebus
1
Ja, pensé en hacerlo sonar intencionalmente desagradable, pero soy nuevo aquí y no estaba seguro de cómo la comunidad tomaría eso :).
karlcyr

Respuestas:

7

Cual es tu sistema operativo? (No puedo agregar comentarios).

Para Solaris obtenemos mejores resultados primero forzando un volcado de núcleo ( gcore <pid>) y luego adjuntando jmap al archivo de volcado de núcleo ( jmap -heap:format=b <path to java bin> <path to core>)

gcorees una utilidad * nix para generar una imagen de un programa en ejecución. Ver enlace .

Fglez
fuente
Lo probé con gdb en Linux y funciona muy bien.
Christian
que JDK tiene "gcore"? mío, Sun 32 bit jdk para linux 1.6.0.20 no lo tiene.
djangofan
Editado con aclaración gcore.
fglez
2

Tenemos un JSP que consulta ManagementFactory.getThreadMXBean () y produce un informe. Puede que no sea útil cuando la aplicación se ha bloqueado, pero si realiza una encuesta cada minuto, tendrá una idea de lo que está sucediendo.

Más información aquí.

rytis
fuente
2

puede monitorear su aplicación a través de jmx desde el exterior. cuando conozca algunas métricas que indican un OutOfMemory próximo, puede activar una ejecución de jmap antes de que se genere la excepción.

cristiano
fuente
Gracias Christian: ¿es más probable que jmap sea confiable antes de que se produzca el error?
karlcyr
jmap aún necesitará algo de tiempo para obtener un volcado de almacenamiento dinámico. pero obtendrá un montón completo siempre que su jvm / tomcat sea el principal responsable.
Christian
Creo que la herramienta más limpia y fácil para hacer esto es "Visual VM". Puede estar fuera del alcance, pero crear un complemento personalizado para VisualVM que detecte la condición y tome el volcado automático desde VisualVm sería increíble en mi humilde opinión.
djangofan
2

Gracias a todos por sus sugerencias.

Lo que terminamos haciendo es escribir un script para monitorear activamente los registros de recolección de basura. En nuestra experiencia, los GC completos consecutivos casi siempre preceden a un OOM, por lo que nuestro script detecta este evento, elimina con gracia el servidor del grupo de equilibrio de carga y fuerza el volcado del montón. Esto ha aumentado considerablemente nuestra efectividad.

karlcyr
fuente
2

Esta es una pregunta bastante antigua, pero responderé con la esperanza de que alguien pueda encontrarla útil.

jmap tiene una opción -F (forzar). Esto ha demostrado no funcionar tan bien en el pasado para mí. Si va a utilizar la opción -F, le recomendaría que también especifique el directorio java.io.tmp como parte del comando jmap. Hubo un problema con JVM versión 1.6.22 en el que la utilidad jmap no funcionaba correctamente debido a una configuración de directorio temporal.

También puede intentar realizar un volcado de núcleo mediante gdb. Una vez que tenga el núcleo, jmap puede convertir el núcleo en un volcado de almacenamiento dinámico.

Nick Hristov
fuente