2009-08-13 14 views
5

que he tenido esta experiencia preocupante con un servidor Tomcat, que dice:reducir los espacios para llevar a sobrevivientes continua GC completa

  • nuestro servidor Hudson;
  • una versión provisional de nuestra aplicación web, redesplegada 5-8 veces por día.

El problema es que terminamos con la recolección continua de basura, pero la generación anterior está lejos de llenarse. Me he dado cuenta que los espacios de sobrevivientes están al lado de inexisting, y la salida del colector de basura es similar a:

[GC 103688K->103688K(3140544K), 0.0226020 secs] 
[Full GC 103688K->103677K(3140544K), 1.7742510 secs] 
[GC 103677K->103677K(3140544K), 0.0228900 secs] 
[Full GC 103677K->103677K(3140544K), 1.7771920 secs] 
[GC 103677K->103677K(3143040K), 0.0216210 secs] 
[Full GC 103677K->103677K(3143040K), 1.7717220 secs] 
[GC 103679K->103677K(3143040K), 0.0219180 secs] 
[Full GC 103677K->103677K(3143040K), 1.7685010 secs] 
[GC 103677K->103677K(3145408K), 0.0189870 secs] 
[Full GC 103677K->103676K(3145408K), 1.7735280 secs] 

La información montón antes de reiniciar Tomcat:

Attaching to process ID 10171, please wait... 
Debugger attached successfully.    
Server compiler detected.      
JVM version is 14.1-b02      

using thread-local object allocation. 
Parallel GC with 8 thread(s)   

Heap Configuration: 
    MinHeapFreeRatio = 40 
    MaxHeapFreeRatio = 70 
    MaxHeapSize  = 3221225472 (3072.0MB) 
    NewSize   = 2686976 (2.5625MB) 
    MaxNewSize  = 17592186044415 MB  
    OldSize   = 5439488 (5.1875MB) 
    NewRatio   = 2      
    SurvivorRatio = 8      
    PermSize   = 21757952 (20.75MB) 
    MaxPermSize  = 268435456 (256.0MB) 

Heap Usage: 
PS Young Generation 
Eden Space: 
    capacity = 1073479680 (1023.75MB) 
    used  = 0 (0.0MB) 
    free  = 1073479680 (1023.75MB) 
    0.0% used 
From Space: 
    capacity = 131072 (0.125MB) 
    used  = 0 (0.0MB) 
    free  = 131072 (0.125MB) 
    0.0% used 
To Space: 
    capacity = 131072 (0.125MB) 
    used  = 0 (0.0MB) 
    free  = 131072 (0.125MB) 
    0.0% used 
PS Old Generation 
    capacity = 2147483648 (2048.0MB) 
    used  = 106164824 (101.24666595458984MB) 
    free  = 2041318824 (1946.7533340454102MB) 
    4.943684861063957% used 
PS Perm Generation 
    capacity = 268435456 (256.0MB) 
    used  = 268435272 (255.99982452392578MB) 
    free  = 184 (1.7547607421875E-4MB) 
    99.99993145465851% used 

Las banderas de JVM pertinentes pasó a Tomcat es:

-verbose:gc -Dsun.rmi.dgc.client.gcInterval=0x7FFFFFFFFFFFFFFE -Xmx3g -XX:MaxPermSize=256m 

Tenga en cuenta que los espacios para sobrevivientes tienen un tamaño de aproximadamente 40 MB al inicio.

Cualquier idea sobre cómo puedo evitar este problema sería apreciada.


actualizaciones:

La versión JVM es

$ java -version 
java version "1.6.0_15" 
Java(TM) SE Runtime Environment (build 1.6.0_15-b03) 
Java HotSpot(TM) 64-Bit Server VM (build 14.1-b02, mixed mode) 

Voy a mirar en topa con el tamaño PermGen y ver si eso ayuda - probablemente el dimensionamiento del sobreviviente espacios no relacionados.

+0

http://stackoverflow.com/questions/11339679/100-full-eden-space-0-used-survivor-space-garbage-collection-not-done/28421053#28421053 –

Respuesta

12

La clave es probablemente PS Perm Generation que es al 99,999% (sólo 184 bytes de 256 MB *** *** libre).

Por lo general, le sugiero que le de más perm gen pero ya le dio 256MB, que debería ser suficiente. Supongo que tienes una pérdida de memoria en alguna biblioteca de generación de código. Perm Gen se usa principalmente para bytecode para clases.

+1

Tienes razón, lo hace máximo el espacio 'PermGen'. No me había dado cuenta antes, ya que esperaba arrojar un 'OutOfMemoryError', como suele ocurrir. Lo intentaré. –

+1

En cuanto a tener una fuga de generación de código, (lamentablemente) he llegado a ver este problema de PermGen en cualquier aplicación web no trivial. Simplemente estamos redistribuyendo una aplicación basada en Spring. –

+0

Quedarse sin PermGen después de muchas reubicaciones es un problema común; pero aún puedes descubrir quién pierde las clases. Simplemente use el generador de perfiles como lo haría normalmente, pero verifique si hay objetos que no se limpian (recursos, conexiones de DB, etc.). –

4

Creo que esto no es poco común para un servidor de aplicaciones que se despliega continuamente. El espacio de la memoria permanente, que está lleno para ti, es donde van las clases. Tenga en cuenta que los JSP se compilan como clases de Java, y cuando se cambia un JSP, se genera y carga una nueva clase.

Hemos tenido este problema, y ​​nuestra solución es que el servidor de la aplicación se reinicie ocasionalmente.

Esto es lo que haría:

  1. Implementación Hudson a un servidor independiente del servidor de transición
  2. Configurar Hudson para reiniciar el servidor de transición de vez en cuando. Puede hacerlo de dos maneras:
    1. Reinicie periódicamente (p. Ej., todas las noches a medianoche, independientemente de si hay actividad de construcción); o
    2. Haga que el trabajo de implementación de la aplicación web active el trabajo de reinicio del servidor. Si hace esto, asegúrese de que hay un período realmente largo de silencio para el trabajo de reinicio (configuramos el nuestro en 2 horas), para que no se reinicie el servidor en cada compilación (es decir, si dos implementaciones de aplicaciones web suceden en 2 horas , solo activarán un reinicio del servidor).
+0

Tuve el mismo problema y usé la misma solución para una versión provisional de mi aplicación web que Hudson desplegaría en cada compilación. ¿Solución? Simplemente reinicie este Tomcat cada hora, lo cual está bien con nosotros, ya que solo se usa para las pruebas. –

4

La bandera -XX:SurvivorRatio establece la relación entre Eden y los espacios sobrevivientes. De acuerdo con JDK 1.5 tuning doc, el valor predeterminado es 32, lo que da una proporción de 1:32. Esto está de acuerdo con lo que estás viendo. A mí me parece increíblemente pequeño, aunque entiendo que se espera que solo un pequeño número de objetos se dirijan desde el Edén al espacio de los supervivientes.

Por lo tanto, suponiendo que tiene muchos objetos de larga vida, debe disminuir la proporción de supervivientes. El riesgo es que solo tenga esos objetos de larga vida durante una fase de arranque, y por lo tanto, está limitando el tamaño de Eden. Para un servidor de prueba, dudo que esto sea un problema.

Probablemente también reduzca el tamaño del espacio Eden, aumentando -XX:NewRatio (el valor predeterminado es 3). Mi instinto me dice que cien mil o más es suficiente para la generación joven, y que aumentará el costo de la recolección de basura para tener una cantidad tan grande de espacio asignado (es decir, el objeto vivirá en Eden demasiado tiempo). Pero eso es solo instinto, y definitivamente debe ser validado para su entorno.


Y un comentario semi-relacionados, después de leer las respuestas: si usted no está viendo los errores de funcionamiento de espacio PermGen, no gastar su tiempo jugando con él. El permgen se administra por separado del resto del montón.

+0

Que 14.1 es la compilación HS, no la versión java. Actualizaré la pregunta con los detalles. –

+0

OK, eliminaré esa sección de la publicación; pensé que era extraño y quería llamarlo. – kdgregory

6

Es muy fácil tener fugas de ClassLoader: basta con que un objeto cargado a través del ClassLoader sea referido por un objeto que no cargó. Una aplicación constantemente redistribuida llenará rápidamente PermGenSpace.

This article explica qué buscar, y a followup describe cómo diagnosticar y solucionar el problema.

Cuestiones relacionadas