2011-03-25 10 views
8

Tiene una pregunta de asignación de memoria con la que me gustaría su ayuda. Hemos analizado algunos de nuestros servicios en la parte superior y observamos que tienen un valor de RES de aproximadamente 1,8 GB, que por lo que yo entiendo significa que están aferrados a 1,8 GB de memoria en ese momento. Lo cual estaría bien si los hubiéramos iniciado (básicamente, leen desde un caché, procesan y se trasladan a otro caché) pero dado que todavía vemos esto después de que el procesamiento intensivo de CPU se completa, nos preguntamos si significa que algo no está siendo sometido a GC como esperábamos.Tamaño de montón inesperadamente grande en comparación con% utilizado

corremos el programa con los siguientes parámetros: -Xms256m -Xmx3096m, que según entiendo significa un tamaño inicial del almacenamiento dinámico de 256 y un tamaño máximo de almacenamiento dinámico de 3096.

Ahora lo que haría esperar para ver es que el montón crece según sea necesario inicialmente, y luego se contrae según sea necesario a medida que la memoria se desasigna (aunque este podría ser mi primer error). Lo que vemos con jvisualvm es la siguiente:

  • 3 minutos en: Montón utilizado es de 1 GB, montón tamaño es de 2 GB
  • 5 minutos en: hemos hecho procesamiento, por lo montón usada cae dramáticamente a cerca de suficiente nada de nada, tamaño del montón sin embargo sólo gotas a alrededor de 1,5 GB
  • 7 mins ->: pequeños trozos de tiempo real procesamiento periódicamente, montón utilizados solamente siempre entre 100-200MB o así, tamaño del montón sin embargo permanece constante a aproximadamente 1.7GB.

Mi pregunta sería, ¿por qué no se ha reducido mi montón como quizás esperaba? ¿No es esto robar otros procesos en la caja de linux de la memoria valiosa, y si es así cómo podría solucionarlo? Vemos errores de memoria en ocasiones, y con estos procesos asignados al tamaño de memoria más "inesperado", pensé que era mejor comenzar con ellos.

Cheers, Dave.

(~ disculpen posible falta de entendimiento sobre la optimización de la memoria JVM!)

+0

Asigne un poco más de intercambio a la caja, tal vez. Como muchas de estas páginas no se utilizan, el núcleo las puede ubicar sin causar basura. Otros procesos deberían estar bien para la memoria residente. – wds

Respuesta

2

Es posible que desee ver this answer acerca de la expansión y reducción de la pila de sintonización. Por defecto, la JVM no es demasiado agresiva para reducir el montón. Además, si el montón tiene suficiente espacio libre durante un largo período de tiempo, no activará un GC, que creo que es el único momento en que se considera reducirlo.

Lo ideal es que configure el máximo a un valor que proporcione a su aplicación suficiente espacio libre bajo carga completa, pero que sea aceptable para el rendimiento del sistema operativo si siempre estuviera en uso.No es raro establecer el mínimo al máximo para la previsibilidad y el rendimiento potencialmente mejor (no tengo nada que hacer referencia para ese improvisado).

+0

Gracias WhiteFang. Es hora de mirar una reducción del montón más agresiva, creo. – f1dave

+0

La otra cosa que me pregunto es si este tipo de cosa depende del sistema operativo. ¿Manejará Linux los problemas de memoria/pila de una manera diferente a decir, Windows, etc.? – f1dave

+0

En general, creo que el sistema operativo no tiene importancia para el ajuste de memoria/pila. Estoy seguro de que hay diferencias menores para explicar los detalles del sistema operativo, pero la JVM generalmente está diseñada para comportarse de la misma manera. Solaris tiende a tener algunas perillas adicionales, pero dudo que ayude mucho. – WhiteFang34

1

no tengo una respuesta completa, pero a similar question has come up before. De la discusión anterior debe investigar -XX:MaxHeapFreeRatio= como su parámetro de ajuste para forzar la liberación del montón de vuelta al sistema operativo. Hay documentation here, y creo que el valor predeterminado permite que una gran cantidad de montón no utilizado permanezca como propiedad de la JVM.

0

Bueno, el GC no siempre se ejecuta cuando uno piensa y no siempre recoge lo que es elegible. También podría comenzar a recolectar objetos del antiguo espacio genético si se queda sin espacio (ya que la recopilación de datos antiguos normalmente implicaría una colección stop-the-world que el GC trata de evitar hasta que realmente necesite hacerlo). eso).

0

Tal vez podría probar algunos perfiles, con TPTP, visualvm o JProbe (comercial, pero de prueba disponible), para averiguar exactamente qué sucede.

Otra cosa a tener en cuenta es el manejo de archivos; No tengo los detalles, pero uno de mis colegas encontró hace un par de años un problema de saturación de pila causado por un proceso que abrió muchos archivos, y descubrió que cada vez que abría uno se asignaba un buffer de 4kb en el montón nativo, liberado al final de su procesamiento. Espero que estas indicaciones bastante vagas puedan ayudar ...

+0

Gracias zim - pero ya he estado mirando a través de visualvm, que es cómo obtuve las cifras en la pregunta original. – f1dave

Cuestiones relacionadas