Analizar problemas de memoria

Descripción

Entorno
Experience Manager

Problema/Síntomas
La aplicación java se ejecuta más lentamente y finalmente se queda sin memoria o se ve un error en los registros o en la salida de la consola OutOfMemoryError: Java heap space o OutOfMemoryError: gc overhead limit exceeded.

Resolución

Causa

Estos problemas pueden tener muchas causas.

Una posible causa es que la aplicación java, en nuestro caso, CRX / CQ se inició desde la línea de comandos con la configuración predeterminada de memoria de pila de Java. Esto significa que no se ha especificado -Xmx el parámetro jvm. CRX o CQ necesitan al menos 256 MB de memoria asignados para funcionar. Si este es el problema, asegúrese de que los ajustes de memoria estén configurados, empezando por la línea de comandos. Ejemplo:

java -Xmx512m -jar *.jar

Si este no es el caso, su aplicación podría estar reteniendo demasiados objetos sin liberarlos para la recolección de basura. Esto se llama una fuga de memoria. Haga clic aquí para más información. Consulte la sección siguiente sobre cómo analizar los problemas de memoria en las aplicaciones java.

Crear volcado de montículos
Generación automática de volcado de montículos

Para crear automáticamente un volcado de montículos cuando se queda sin memoria, puede añadir el parámetro jvm -XX:+HeapDumpOnOutOfMemoryError para generar un volcado de montículos automáticamente cuando la aplicación lanza un OutOfMemoryError. Por ejemplo,

java -Xmx256m -XX:+HeapDumpOnOutOfMemoryError -jar *.jar

Esto genera un archivo de volcado de montículos (java_...hprof) en el directorio de trabajo del proceso siempre que el proceso java se quede sin memoria. El proceso puede seguir ejecutándose después de que se haya generado el volcado. Normalmente, un archivo de volcado es suficiente para analizar el problema.

Nota: si está usando un script crx-quickstart/server/start para iniciar su instancia de CRX, entonces puede añadir -XX:+HeapDumpOnOutOfMemoryError a la variable CQ_JVM_OPTS (asegúrese de que la variable también esté descomentada). Por ejemplo:

CQ_JVM_OPTS='-XX:+HeapDumpOnOutOfMemoryError'

Después de añadir este parámetro y de reiniciar la instancia CRX, verifique si la nueva opción jvm está establecida. Ejecute ps -ef | grep java desde la línea de comandos. A continuación, compruebe si ve -XX:+HeapDumpOnOutOfMemoryError como parámetro del proceso java CRX.

Si necesita especificar un directorio diferente en el que generar el volcado de la pila debido a restricciones de espacio en el disco, puede añadir el parámetro -XX:HeapDumpPath=/path/to/generate/heapdump para indicarle a jvm dónde colocar el archivo.

Aquí tiene una referencia de los parámetros jvm relacionados con la depuración.

Generar manualmente un volcado de montículos

JVM Sun/Oracle

Para generar manualmente un volcado de la pila, ejecute este comando (jmap y jps se encuentran en la carpeta bin de su directorio principal de jdk):

  1. busque el pid del proceso java para el que está generando un volcado de montículos.

    • En Unix o Linux esto se puede hacer con ps -ef | grep java o jps -l
    • En Windows esto se puede hacer abriendo el administrador de tareas, pulse Ctrl+Shift+Esc a continuación, vaya a Ver = Seleccionar columnas = PID (identificador de proceso) o jps -l
  2. Ejecute el comando jmap que aparece a continuación, sustituya /path/to/generate/heapdumpfile.hprof por la ubicación en la que desee generar el archivo de volcado de la pila, y sustituya 1234 por el pid que buscó en el paso anterior.

    jmap -dump:format=b,file=/path/to/generate/heapdumpfile.hprof 1234
    

IBM JVM

Primero tendrá que cambiar la configuración por defecto de JVM con respecto a los agentes de volcado para generar los volcados correctos a señal de usuario. Hay varios tipos de volcados, pero generalmente se necesita el volcado completo del sistema para realizar un análisis exhaustivo de la memoria. Añada los siguientes argumentos:

Xdump:heap:opts=PHD+CLASSIC:events=user -Xdump:system:events=user

Este evento de "usuario" ocurre cuando la JVM recibe la señal SIGQUIT (Linux, AIX®, z/OS® e i5/OS™) o SIGBREAK (Windows) del sistema operativo.

Para obtener más información, consulte la documentación del fabricante aquí.

Advertencia: Los archivos de volcado de montículos son grandes y pueden tener el mismo tamaño en disco que la configuración del parámetro max heap -Xmx jvm. Compruebe que tenga suficiente espacio en el disco asignado al directorio donde se genera el archivo de volcado.

Analizar volcado de montículos

Una buena herramienta para analizar los volcados de montículos es EclipseMAT (Eclipse Memory Analyzer): http://www.eclipse.org/mat/

Esta herramienta no puede analizar los volcados generados por IBM JVM. Existen varias posibilidades para ello. IBM HeapAnalyzer le servirá para los volcados de pila en formato PHD o clásico.

Para realizar un análisis completo del volcado del sistema, utilice la variable Área de trabajo del asistente de asistencia de IBM, con Herramientas de diagnóstico y supervisión de IBM para Java: Analizador de memoria versión 1.2 instalado en la parte superior.

Histograma de montículos

El histograma de montículos es una simple medición del número de objetos vivos y memoria utilizados por cada clase Java. Lamentablemente, según la instalación de Java, es posible que las herramientas necesarias no estén disponibles o que no siempre funcionen. Para crear un histograma en montículo, primero necesita el id de proceso del proceso Java. Para obtenerlo, ejecute ps o (si está disponible):

jps -l

Esta herramienta Java obtiene los ID de proceso de todos los procesos Java en ejecución. Ejemplo:

327
3332 sun.tools.jps.Jps
3313 crx-quickstart-....jar

Ahora ejecute el siguiente comando:

jmap -histo 3313

La lista está ordenada por la memoria total requerida (poco profunda: excluyendo los objetos referenciados). Las primeras 20 líneas de la salida son las más interesantes. Ejemplo de salida:

JVM version is 1.5.0_20-141
Iterating over heap. This may take a while...
Warning: skipping invalid TLAB for thread t@62211
Warning: skipping invalid TLAB for thread t@62467
...
SizeCountClass description
-------------------------------------------------------
1059290412916byte
1028584075255* ConstMethodKlass
628317658388char
604230414928int
4995752116201* SymbolKlass
422089675255* MethodKlass
41965126969* ConstantPoolKlass
29285606969* InstanceKlassKlass
26310086066* ConstantPoolCacheKlass
2395872149742org.apache.jackrabbit.core.query.lucene.DocId$PlainDocId
14760087003java.util.HashMap$Entry
139612858172java.lang.String
107023244593java.util.HashMap$Entry
75398410036short
73546454org.apache.jackrabbit.core.query.lucene.DocId
7201927502java.lang.Class
64070413348com.day.crx.persistence.tar.index.IndexEntry
...

Más información

Para ayudar a analizar el problema, también necesitamos conocer la siguiente información:

  • Versión de CRX o CQ, así como un listado de los números de versión de todas las revisiones instaladas.
  • Sistema operativo, proveedor de JVM y versión.

Referencias

http://java.sun.com/javase/6/webnotes/trouble/TSG-VM/html/memleaks.html
http://java.sun.com/javase/technologies/hotspot/vmoptions.jsp#DebuggingOptions

En esta página