Diferente consumo de memoria con configuraciones similares.

Diferente consumo de memoria con configuraciones similares.

Tengo dos instancias de Tomcat 7 diferentes en dos servidores diferentes (Oracle jdk7) con una configuración de hardware casi igual (ambas > 24 GB de RAM). Ambos servidores Tomcat tienen la misma configuración y se implementan las mismas aplicaciones web en estos servidores. Las opciones de catalina son las siguientes:

-XX:PermSize=128m -XX:MaxPermSize=512M -Xmx2048m -XX:+CMSIncrementalMode -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC

Mientras se ejecuta una prueba de carga (haciendo hincapié en una API REST con numerosas solicitudes ejecutadas en paralelo), uno de los servidores arroja java.lang.OutOfMemoryError: Java heap space(aquí está el seguimiento de pila:http://pastebin.com/wuS1MVCC), el otro servidor funciona bien. No tengo idea de por qué sucede esto. ¿Alguien se ha enfrentado alguna vez a un problema similar?

Respuesta1

Entonces, lo que está sucediendo es que una de sus JVM de Tomcat está intentando exceder los 2048 MB de almacenamiento dinámico que le asignó.

Parece que estás buscando tanto una respuesta específica como una lista de verificación de cosas para probar, así que aquí tienes:

Quedarse sin montón se debe a una pérdida de memoria, donde se pierde un poco con cada solicitud, o en un escenario de carga puede deberse a que simplemente está arrojando a la JVM más de lo que puede manejar. Desea identificar cuál de ellos es el problema, así que comience observando cómo genera su carga.

Si el problema ocurre solo en un nivel alto de solicitudes paralelas pero nunca en un nivel inferior, entonces tiene el problema de que la cantidad de solicitudes multiplicada por la memoria requerida para procesar cada solicitud es demasiado grande. Debe hacer que cada solicitud utilice menos memoria o limitar la concurrencia de alguna manera.

Si el problema ocurre después de que se haya procesado una cierta cantidad de solicitudes independientemente de la simultaneidad, entonces tiene una pérdida de memoria. Necesitas encontrarlo y recuperar la memoria.

En cualquier escenario, será de gran ayuda tener un buen analizador de memoria dinámica. Los hay buenos comerciales como YourKit Java Profiler o gratuitos como Eclipse Memory Analyzer. Encuentre una herramienta que funcione para usted y aprenda a usarla para ver qué está consumiendo memoria. Tenga en cuenta que no necesariamente necesita usar la herramienta para iniciar su programa; si está ejecutando una prueba de carga en un servidor, puede usar la herramienta de línea de comandos jmap del JDK para capturar un volcado de montón en un archivo, y luego use su herramienta para analizar el archivo de volcado. La herramienta le mostrará qué objetos están ocupando espacio en su montón.

Respuesta2

Hayalgodiferente entre los dos sistemas, de lo contrario el comportamiento no sería diferente. Tenga en cuenta que dedicar demasiado tiempo a GC para obtener muy pocos resultados también puede provocar el error. Correr cerca de los límites del montón hace que el GC tenga este tipo de problema.

Tiempo excesivo de GC y OutOfMemoryError

El recolector concurrente generará un OutOfMemoryError si se dedica demasiado tiempo a la recolección de basura: si se dedica más del 98 % del tiempo total a la recolección de basura y se recupera menos del 2 % del montón, se generará un OutOfMemoryError. Esta característica está diseñada para evitar que las aplicaciones se ejecuten durante un período de tiempo prolongado mientras realizan poco o ningún progreso porque el montón es demasiado pequeño. Si es necesario, esta función se puede desactivar agregando la opción -XX:-UseGC OverheadLimit a la línea de comando.

información relacionada