2011-08-24 29 views
8

He encontrado la infame OutOfMemoryException en mi aplicación y en lugar de simplemente aumentar la cantidad de Heap Space disponible traté de ver cuál era el problema, por si acaso, había algún tipo de pérdida de mi aplicación.Java Heap Space - ¿Cómo funciona -Xmx exactamente?

He añadido el parámetro JVM -XX: + HeapDumpOnOutOfMemoryError que crea un Heap Dump cuando se encuentra el error OutOfMemory. Luego analicé el archivo de volcado producido con diferentes herramientas de creación de perfiles. Luego comencé a jugar con el parámetro -Xmx y observar patrones.

Lo que me desconcertó es lo siguiente. ¿Por qué al analizar el volcado descubrí que el tamaño total de todos los objetos era mucho menor que el total que establecí usando el parámetro -Xmx? Por ejemplo, digamos que configuro -Xmx a '2048m'. Cuando analicé el archivo de volcado, encontré un total de 400Mb de objetos en el Heap. Esperaba encontrar 2GB. ¿Me estoy perdiendo de algo?

+0

¿Ha comprobado que su OOME en realidad menciona la memoria del montón? Hay algunos casos (relativamente poco frecuentes) en los que se lanzan OOMEs, pero NO es el montón lo que está lleno. –

+1

Derecha, @Joachim, demasiados hilos en JVM x86 también se cuelga con la excepción OOM – aalku

Respuesta

3

Vuelva a leer su mensaje de error; puede indicarle qué tipo de memoria se le acabó. Supongo que era el espacio PermGen. Permgen se usa para definiciones de clases (entre otras cosas). Puede ajustar el espacio para PermGen a través del -XX: MaxPermSize PermGen no es parte del montón, por lo que no se incluye en el volcado del montón.

Consulte this answer para obtener más información sobre cómo mirar PermGen.

Si este no es el problema, intente configurar su tamaño de almacenamiento dinámico inicial (-Xms) al mismo valor máximo. Hacer esto significa que el montón no crecerá, lo que debería facilitar la comprensión de lo que sucede.

Recomiendo usar jvisualvm (parte del JDK) para ver la utilización de la memoria mientras se ejecuta el programa.

+0

Puede ser interesante .... Sí, el error que obtuve fue este. Probando esto, se. Publicaremos de nuevo con los resultados. – Kros

+0

Usé el -XX: MaxPermSize y tuve problemas desde entonces. Creo que los últimos cambios en mi aplicación han llevado a superar un umbral que causaba la excepción. Gracias por tu ayuda. – Kros

5

Supongo que como los GC modernos dividen el montón en áreas de memoria separadas (generaciones jóvenes/permanentes/permanentes), es suficiente que el espacio de generación permanente se llene por completo para que ocurra un error de falta de memoria. Puede configurar la proporción de espacios de generación diferentes utilizando varias opciones de línea de comandos de JVM.

Aquí hay un buen artículo sobre Tuning Garbage Collection with the 5.0 Java[tm] Virtual Machine (No pude encontrar uno más reciente, pero creo que los conceptos básicos aún se aplican en máquinas virtuales más nuevas).

Cuestiones relacionadas