Mensajes de registro de recolección de basura de Java

96

He configurado Java para volcar información de recolección de basura en los registros ( GC detallado ). No estoy seguro de qué significan las entradas de recolección de basura en los registros. A continuación se publica una muestra de estas entradas. He buscado en Google y no he encontrado explicaciones sólidas.

Tengo algunas suposiciones razonables, pero estoy buscando respuestas que brinden definiciones estrictas de lo que significan los números en las entradas, respaldadas por fuentes confiables. Un +1 automático a todas las respuestas que citan documentación solar. Mis preguntas son:

  1. ¿A qué se refiere PSYoungGen? Supongo que tiene algo que ver con la generación anterior (¿más joven?), Pero ¿qué es exactamente?
  2. ¿Cuál es la diferencia entre el segundo triplete de números y el primero?
  3. ¿Por qué se especifica un nombre (PSYoungGen) para el primer triplete de números pero no para el segundo?
  4. ¿Qué significa cada número (tamaño de la memoria) en el triplete? Por ejemplo, en 109884K-> 14201K (139904K), es la memoria antes de GC 109884k y luego se reduce a 14201K. ¿Qué importancia tiene el tercer número? ¿Por qué necesitaríamos un segundo conjunto de números?

8109.128: [GC [PSYoungGen: 109884K-> 14201K (139904K)] 691015K-> 595332K (1119040K), 0.0454530 segundos]

8112.111: [GC [PSYoungGen: 126649K-> 15528K (142336K)] 707780K-> 605892K (1121472K), 0.0934560 s]

8112.802: [GC [PSYoungGen: 130344K-> 3732K (118592K)] 720708K-> 607895K (1097728K), 0.0682690 s]

Ethan Heilman
fuente
montón completo, parte de generación joven del montón, gc menor para saber
MarianP

Respuestas:

90

La mayor parte se explica en la Guía de ajuste de GC (que haría bien en leer de todos modos).

La opción de línea de comando -verbose:gchace que la información sobre el montón y la recolección de basura se imprima en cada recolección. Por ejemplo, aquí se obtiene la salida de una aplicación de servidor grande:

[GC 325407K->83000K(776768K), 0.2300771 secs]
[GC 325816K->83372K(776768K), 0.2454258 secs]
[Full GC 267628K->83769K(776768K), 1.8479984 secs]

Aquí vemos dos colecciones menores seguidas de una colección principal. Los números antes y después de la flecha (por ejemplo, 325407K->83000Kdesde la primera línea) indican el tamaño combinado de los objetos vivos antes y después de la recolección de basura, respectivamente. Después de recolecciones menores, el tamaño incluye algunos objetos que son basura (que ya no están vivos) pero que no se pueden recuperar. Estos objetos están contenidos en la generación titular o se hace referencia a las generaciones titulares o permanentes.

El siguiente número entre paréntesis (por ejemplo, de (776768K)nuevo desde la primera línea) es el tamaño comprometido del montón: la cantidad de espacio utilizable para los objetos java sin solicitar más memoria al sistema operativo. Tenga en cuenta que este número no incluye uno de los espacios de supervivientes, ya que solo se puede usar uno en un momento dado, y tampoco incluye la generación permanente, que contiene los metadatos utilizados por la máquina virtual.

El último elemento de la línea (por ejemplo, 0.2300771 secs) indica el tiempo necesario para realizar la recolección; en este caso aproximadamente un cuarto de segundo.

El formato de la colección principal en la tercera línea es similar.

El formato de la salida producida por -verbose:gcestá sujeto a cambios en versiones futuras.

No estoy seguro de por qué hay un PSYoungGen en el suyo; ¿Cambiaste el recolector de basura?

Michael Myers
fuente
¿Dónde encontrar los archivos de registro de gc?
Mr Lou
7
Esta respuesta realmente no aborda las preguntas originales. Siento que la respuesta de Michaeljoseph es mejor. Aborda las preguntas formuladas por Ethan y hace un mejor trabajo al desglosar el ejemplo original. Si bien hay dos problemas en su respuesta (su enlace ahora está muerto y rafa.ferreria ha señalado el otro), no solo regurgita un documento de Oracle.
Dirk
127
  1. PSYoungGen se refiere al recolector de basura en uso para la recolección menor. PS son las siglas de Parallel Scavenge.
  2. El primer conjunto de números son los tamaños antes / después de la generación joven y el segundo conjunto son para todo el montón. (El diagnóstico de un problema de recolección de basura detalla el formato)
  3. El nombre indica la generación y el colector en cuestión, el segundo conjunto es para todo el montón.

Un ejemplo de un GC completo asociado también muestra los recolectores utilizados para las generaciones antiguas y permanentes:

3.757: [Full GC [PSYoungGen: 2672K->0K(35584K)] 
            [ParOldGen: 3225K->5735K(43712K)] 5898K->5735K(79296K) 
            [PSPermGen: 13533K->13516K(27584K)], 0.0860402 secs]

Finalmente, desglosando una línea de su salida de registro de ejemplo:

8109.128: [GC [PSYoungGen: 109884K->14201K(139904K)] 691015K->595332K(1119040K), 0.0454530 secs]
  • 107Mb usados ​​antes de GC, 14Mb usados ​​después de GC, tamaño máximo de generación joven 137Mb
  • 675Mb montón utiliza antes de GC, 581Mb montón utilizado después de GC, de 1 Gb tamaño del montón max
  • menor GC ocurrió 8109.128 segundos desde el inicio de la JVM y tomó 0.04 segundos
michaeljoseph
fuente
8
solo un comentario menor, el valor entre '()' no es el tamaño máximo, por siempre, es el tamaño máximo por el momento. Si el GC no puede liberar el montón menos, este límite será necesario para el sistema operativo y este valor aumentará. Respetando por supuesto el límite definido en: -Xmx
rafa.ferreira
@ rafa.ferreira Creo que el valor en paranthesis, es decir, 1119040K es el tamaño del montón comprometido. No creo que GC imprima el tamaño de 'montón máximo' en cualquier lugar. Referencia 1 y Referencia 2
rohitmohta
23

Solo quería mencionar que se puede obtener el registro GC detallado con el

-XX:+PrintGCDetails 

parámetro. Luego verá la salida de PSYoungGen o PSPermGen como en la respuesta.

También -Xloggc:gc.logparece generar la misma salida, -verbose:gcpero puede especificar un archivo de salida en el primero.

Uso de ejemplo:

java -Xloggc:./memory.log -XX:+PrintGCDetails Memory

Para visualizar mejor los datos, puede probar gcviewer (se puede encontrar una versión más reciente en github ).

¡Tenga cuidado de escribir los parámetros correctamente, olvidé el "+" y mi JBoss no se iniciaba sin ningún mensaje de error!

Andrei
fuente
3
Tenga en cuenta que gc.log se sobrescribirá cuando se reinicie java (por ejemplo, si reinicia su tomcat porque tenía problemas de memoria y le encantaría ver ese gc.log). O al menos lo hará si rota los registros de GC. Hay muchas otras opciones que controlan el registro de gc. Consulte oracle.com/technetwork/articles/java/vmoptions-jsp-140102.html . En particular, considere-XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=<some number of files> -XX:GCLogFileSize=<some size> -XX:+PrintTenuringDistribution
Dan Pritts