¿Por qué una máquina que ejecuta Java aplicación está casi fuera de la memoria física, pero todavía tiene una duración de semana

kas-bañera:

Tengo una aplicación Java que se implementa en dos máquinas y, a juzgar por los indicadores (incluyendo JMC), ambos casi sin memoria y que tiene una duración de tiempo bastante largo. Sin embargo, las aplicaciones se ejecutan bien y sin errores OutOfMemory suceden.introducir descripción de la imagen aquí

Esto es confuso. ¿Puede usted explicar por qué las aplicaciones corren todavía no tener errores OutOfMemory? ¿Por qué la memoria no quede liberado antes que cuando tan cerca del límite?

PS aquí es la métrica del montón

introducir descripción de la imagen aquí

Jiri Tousek:

Esto es sólo cómo funciona la gestión de memoria de Java - que básicamente se retrasa la recolección de basura hasta que sea necesario, con la esperanza de que la aplicación se cerrará antes de que se necesitaba el GC.

Por lo que a menudo optan por asignar más memoria desde el sistema operativo, hasta un límite determinado, ya sea por -Xmxo por OS / límite total de RAM, y sólo entonces se llevará a cabo importantes ejecuta el recolector de basura. Estas carreras se libere la memoria y luego la aplicación tendrá una duración de algo más de tiempo, hasta encontrarse con el límite una vez más.

Si la aplicación necesita poco más de memoria, entonces lo que sucede después de que llegue al límite de memoria es que las grandes carreras GC obtendrán más y más frecuentes (al aumentar la memoria necesaria, y la memoria se aclaró por GC disminuye) y las carreras de GC se alargará . En algún momento, la máquina virtual puede empezar a pasar más tiempo en GC que se ejecuta la aplicación.

De esta manera, es posible que el proceso de Java se ejecutará durante mucho tiempo (posiblemente "para siempre") y consumir casi toda la memoria disponible, mientras que la aplicación real obtiene el tiempo de ejecución casi no real debido a la casi totalidad tiempo de CPU que se gasta en GC . Java puede detectar esta situación y lanzar una java.lang.OutOfMemoryErrorcon el mensaje GC Overhead Limit Exceeded, pero no siempre lo hace.


Si desea diagnosticar si su aplicación es sólo optimizar el uso de memoria, o es en realidad esencialmente fuera de la memoria, es necesario saber cuánto tiempo pasa en VM GC, y lo que es la tendencia. Algunas maneras posibles:

  • Connect con un JConsole o VisualVM (ambos son partes de la JDK) y comprobar las pistas de GC (intervalos y duraciones)
  • Una forma más fácil si la aplicación Java es-hreaded solo es observar carga de la CPU - GC defecto es multi-hilo, por lo que durante GC ejecutarlo en su mayoría se ejecuta en más procesadores / núcleos y la carga de la CPU será de más de 100% de una de un solo núcleo (> 100% en UNIX top), mientras que una aplicación de un solo hilo sólo causa cargas de hasta 100% de un solo núcleo.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=210055&siteId=1
Recomendado
Clasificación