Colección de basura y documentación de Java 7 (JDK 7) en G1

Java 7 ha estado fuera por un tiempo, pero no puedo encontrar ningún recurso bueno en la configuración de los recolectores de basura , específicamente el nuevo colector G1 .

Mis preguntas:

  1. ¿G1 es el recostackdor predeterminado en Java 7 y, de no ser así, cómo activo G1?
  2. ¿Qué configuraciones opcionales tiene g1 en Java7?
  3. ¿Hubo algún cambio realizado en otros colectores como cms o el colector paralelo en Java 7?
  4. ¿Dónde puedo encontrar buena documentación sobre recolección de basura en Java 7?

El recolector de basura G1 no es el predeterminado en mi instalación de Java, versión 1.7.0_01. Puedes verlo por ti mismo usando algunas opciones adicionales de línea de comando:

> java -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -version -XX:InitialHeapSize=132304640 -XX:MaxHeapSize=2116874240 -XX:ParallelGCThreads=4 -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC java version "1.7.0_01" Java(TM) SE Runtime Environment (build 1.7.0_01-b08) Java HotSpot(TM) 64-Bit Server VM (build 21.1-b02, mixed mode) Heap PSYoungGen total 37696K, used 1293K [0x00000007d5eb0000, 0x00000007d88c0000, 0x0000000800000000) eden space 32320K, 4% used [0x00000007d5eb0000,0x00000007d5ff3408,0x00000007d7e40000) from space 5376K, 0% used [0x00000007d8380000,0x00000007d8380000,0x00000007d88c0000) to space 5376K, 0% used [0x00000007d7e40000,0x00000007d7e40000,0x00000007d8380000) PSOldGen total 86144K, used 0K [0x0000000781c00000, 0x0000000787020000, 0x00000007d5eb0000) object space 86144K, 0% used [0x0000000781c00000,0x0000000781c00000,0x0000000787020000) PSPermGen total 21248K, used 2032K [0x000000077ca00000, 0x000000077dec0000, 0x0000000781c00000) object space 21248K, 9% used [0x000000077ca00000,0x000000077cbfc288,0x000000077dec0000) 

Sin embargo, no es necesario habilitar las opciones experimentales para activar el recostackdor G1:

 > java -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseG1GC -version -XX:InitialHeapSize=132304640 -XX:MaxHeapSize=2116874240 -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseCompressedOops -XX:+UseG1GC -XX:-UseLargePagesIndividualAllocation java version "1.7.0_01" Java(TM) SE Runtime Environment (build 1.7.0_01-b08) Java HotSpot(TM) 64-Bit Server VM (build 21.1-b02, mixed mode) Heap garbage-first heap total 130048K, used 0K [0x000000077ca00000, 0x0000000784900000, 0x00000007fae00000) region size 1024K, 1 young (1024K), 0 survivors (0K) compacting perm gen total 20480K, used 2032K [0x00000007fae00000, 0x00000007fc200000, 0x0000000800000000) the space 20480K, 9% used [0x00000007fae00000, 0x00000007faffc288, 0x00000007faffc400, 0x00000007fc200000) No shared spaces configured. 

No sé dónde puedes encontrar buena documentación.

Oracle finalmente hizo oficial a G1 en Java 7 U4: http://www.oracle.com/technetwork/java/javase/7u4-relnotes-1575007.html

Descripción: http://docs.oracle.com/javase/7/docs/technotes/guides/vm/G1.html

Opciones de línea de comando: http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html#G1Options

Aún así, no creo que sea el recostackdor predeterminado en Java 7. Para los servidores, el predeterminado es el colector paralelo como en Java 6.

Sí, G1 es el nuevo recolector de basura estándar en Java 1.7 JVM.

Aquí puede encontrar mucha información sobre cómo usar y configurar el nuevo recolector de basura:

El uso de G1 G1 todavía se considera experimental y se puede habilitar con los dos parámetros siguientes:

-XX: + UnlockExperimentalVMOptions -XX: + UseG1GC

Para establecer un objective de tiempo de pausa de GC, use el siguiente parámetro:

-XX: MaxGCPauseMillis = 50 (para un objective de tiempo de pausa de 50 ms)

Con G1, se puede especificar un intervalo de tiempo durante el cual una pausa del GC no debería durar más que el tiempo indicado anteriormente:

-XX: GCPauseIntervalMillis = 200 (para un intervalo de intervalo de pausa de 200 ms)

Tenga en cuenta que las dos opciones anteriores representan objectives, no promesas ni garantías. Podrían funcionar bien en algunas situaciones, pero no en otras, y la GC no siempre podría obedecerlas.

Alternativamente, el tamaño de la generación joven se puede especificar explícitamente para impactar los tiempos de pausa de evacuación:

-XX: + G1YoungGenSize = 512m (para una generación joven de 512 megabytes)

G1 también utiliza el equivalente de espacios de supervivencia, que son, naturalmente, un conjunto de regiones (potencialmente no contiguas). Su tamaño se puede especificar con los parámetros habituales (por ejemplo, -XX: SurvivorRatio = 6).

Finalmente, para ejecutar G1 en todo su potencial, intente configurar estos dos parámetros que están deshabilitados de forma predeterminada porque pueden descubrir una rara condición de carrera:

-XX: + G1ParallelRSetUpdatingEnabled -XX: + G1ParallelRSetScanningEnabled

Una cosa más a tener en cuenta es que G1 es muy detallado en comparación con otros GC de HotSpot cuando se configura -XX: + PrintGCDetails. Esto se debe a que imprime tiempos de hilo por GC y otra información muy útil en la creación de perfiles y resolución de problemas. Si desea un registro de GC más conciso, cambie a usar -verbosegc (aunque se recomienda que se obtenga el registro de GC más detallado).

También encontré este artículo muy útil para entender los principios de G1.

Aún más información aquí .

1. Es G1 el colector predeterminado en Java 7 (…)

La regla en esta página de Java 5 sigue siendo aplicable en Java 7 (y AFAIK, Java 8):

En las máquinas de clase servidor que ejecutan la máquina virtual del servidor, el recolector de basura (GC) ha cambiado desde el colector de serie anterior (-XX: + UseSerialGC) a un colector paralelo (-XX: + UseParallelGC).

Pero también considere:

  • Las JVM de 64 bits no vienen con una VM -client , por lo que siempre son “clase de servidor”
  • Desde Java 7, el uso de -XX: + UseParallelGC (ya sea establecido o implícito) implica adicionalmente -XX: + UseParallelOldGC (es decir, a menos que esté explícitamente deshabilitado)

Por ejemplo, si en Windows x64 ejecuta …

  • Java 7 de 64 bits, obtienes Parallel GC (para generaciones jóvenes y antiguas) de forma predeterminada.
  • Java 8 de 32 bits, obtiene el GC serie (para ambas generaciones) de forma predeterminada

1. (…) ¿Cómo activo G1?

A partir de Java 7, simplemente -XX:+UseG1GC . Quizás también sea de interés cuando quieras:

Las aplicaciones que se ejecutan hoy con CMS o el recolector de basura ParallelOld beneficiarían el cambio a G1 si la aplicación tiene uno o más de los siguientes rasgos.

  • Más del 50% del montón de Java está ocupado con datos en vivo.
  • La tasa de asignación de objetos o promoción varía significativamente.
  • Recostackción de basura larga no deseada o pausas de compactación (más de 0,5 a 1 segundo)

2. ¿Qué configuraciones opcionales tiene g1 en Java7?

No he usado G1 por mi cuenta, pero entiendo que se adhiere a las mismas banderas básicas de “rendimiento / ergonómicas” que se usan para sintonizar los otros colectores paralelos. En mi experiencia con el Parallel GC, -XX:GCTimeRatio ha sido la clave para proporcionar la compensación de velocidad-memoria esperada. YMMV.

Las opciones específicas de G1 se enumeran aquí

3. ¿Hubo cambios en (…) cms o el colector paralelo en Java 7?

No lo sé, pero …

G1 está planeado como el reemplazo a largo plazo para el Colector simultáneo de barrido de marcas (CMS)

4. ¿Dónde puedo encontrar buena documentación sobre recolección de basura en Java 7?

Puede ser difícil de encontrar, ¿verdad? Probablemente la mejor página de “centro” que he encontrado es esta:

http://www.oracle.com/technetwork/java/javase/tech/index-jsp-140228.html

Se requiere algo de lectura profunda, pero vale la pena el tiempo si necesitas hacer algo de afinación. Particularmente perspicaz es: Ergonomía del recolector de basura

  1. ¿G1 es el recostackdor predeterminado en Java 7 y, de no ser así, cómo activo G1?

G1 no es un recostackdor predeterminado en Java 7. -XX:+UseG1GC habilitará G1GC

  1. ¿Qué configuraciones opcionales tiene g1 en Java7?

Hay muchos. Eche un vistazo a este artículo de Oracle para obtener información completa.

El GC G1 es un colector de basura adaptativo con valores predeterminados que le permiten trabajar de manera eficiente sin modificaciones.

Por este motivo, personalice los parámetros críticos

 -XX:MaxGCPauseMillis -XX:G1HeapRegionSize -XX:ParallelGCThreads -XX:ConcGCThreads 

y deje todos los demás parámetros al valor predeterminado .

Aquí hay una lista de opciones importantes y sus valores predeterminados. Esta lista se aplica a la última VM Java HotSpot, comstackción 24. Puede adaptar y ajustar la configuración del GC G1 en la línea de comandos de JVM.

Valores predeterminados importantes:

 -XX:G1HeapRegionSize=n 

Establece el tamaño de una región G1. El valor será una potencia de dos y puede oscilar entre 1 MB y 32 MB. El objective es tener alrededor de 2048 regiones basadas en el tamaño mínimo de almacenamiento dynamic de Java.

 -XX:MaxGCPauseMillis=200 

Establece un valor objective para el tiempo máximo de pausa deseado. El valor predeterminado es 200 milisegundos. El valor especificado no se adapta a su tamaño de almacenamiento dynamic.

 -XX:G1NewSizePercent=5 

Establece el porcentaje del montón para usar como el mínimo para el tamaño de generación joven. El valor predeterminado es 5 por ciento de su montón de Java.

 -XX:G1MaxNewSizePercent=60 

Establece el porcentaje del tamaño del montón para usar como el máximo para el tamaño de generación joven. El valor predeterminado es 60 por ciento de su montón de Java.

 -XX:ParallelGCThreads=n 

Establece el valor de los hilos de trabajo STW. Establece el valor de n en la cantidad de procesadores lógicos. El valor de n es el mismo que el número de procesadores lógicos hasta un valor de 8.

Si hay más de ocho procesadores lógicos, establece el valor de n en aproximadamente 5/8 de los procesadores lógicos. Esto funciona en la mayoría de los casos, excepto en los sistemas SPARC más grandes, donde el valor de n puede ser de aproximadamente 5/16 de los procesadores lógicos.

 -XX:ConcGCThreads=n 

Establece el número de hilos de marcado paralelos. Establece n en aproximadamente 1/4 del número de subprocesos paralelos de recolección de basura (ParallelGCThreads).

 -XX:InitiatingHeapOccupancyPercent=45 

Establece el umbral de ocupación del montón de Java que desencadena un ciclo de marcado. La ocupación predeterminada es el 45 por ciento de todo el montón de Java.

 -XX:G1MixedGCLiveThresholdPercent=65 

Establece que el umbral de ocupación para una región antigua se incluya en un ciclo mixto de recolección de basura. La ocupación predeterminada es del 65 por ciento

 -XX:G1HeapWastePercent=10 

Establece el porcentaje de montón que está dispuesto a perder. La máquina virtual Java HotSpot no inicia el ciclo mixto de recolección de elementos no utilizados cuando el porcentaje reclamable es menor que el porcentaje de desechos acumulados

 -XX:G1MixedGCCountTarget=8 

Establece el número objective de colecciones de elementos no utilizados combinados después de un ciclo de marcado para recostackr regiones antiguas con como máximo G1MixedGCLIveThresholdPercent en tiempo real. El valor predeterminado es 8 colecciones mixtas de basura

 -XX:G1OldCSetRegionThresholdPercent=10 

Establece un límite superior en la cantidad de regiones antiguas que se recostackrán durante un ciclo mixto de recolección de basura. El valor predeterminado es 10 por ciento del montón de Java

 -XX:G1ReservePercent=10 

Establece el porcentaje de memoria de reserva para mantener libre a fin de reducir el riesgo de desbordamientos del espacio. El valor predeterminado es 10 por ciento. Cuando aumente o disminuya el porcentaje, asegúrese de ajustar el montón total de Java en la misma cantidad.

Ha reconfigurado muchos parámetros G1GC, que no son necesarios si sigue la página de documentación anterior. Consulte las recomendaciones anteriores, especialmente en ParallelGCThreads y ConcGCThreads , que se basarán en los núcleos de su CPU. Eliminar la reconfiguración de los parámetros innecesarios.

Recomendaciones de Oracle:

Cuando evalúa y ajusta G1 GC, tenga en cuenta las siguientes recomendaciones:

  1. Tamaño de generación joven : Evite establecer explícitamente el tamaño de generación -Xmn con la opción -Xmn o cualquier otra opción relacionada, como -XX:NewRatio . La corrección del tamaño de la generación joven anula el objective del tiempo de pausa objective .

  2. Objetivos de tiempo de pausa: cuando evalúa o sintoniza cualquier colección de basura, siempre hay una latencia frente a la compensación de rendimiento. El G1 GC es un recolector de basura incremental con pausas uniformes, pero también más sobrecarga en los subprocesos de la aplicación. El objective de rendimiento para el G1 GC es el 90% del tiempo de aplicación y el 10% del tiempo de recolección de basura .

  1. ¿Hubo algún cambio realizado en otros colectores como cms o el colector paralelo en Java 7?

Hay algunos cambios con Java 7. Echa un vistazo a este artículo

  1. ¿Dónde puedo encontrar buena documentación sobre recolección de basura en Java 7?

Consulte la página de documentación de Oracle sobre gc y la pregunta SE relacionada:

Colección de basura Java G1 en producción

La documentación disponible en http://www.oracle.com/technetwork/java/javase/tech/g1-intro-jsp-135488.html (el enlace proporcionado por Wojtek) parece ser el único enlace oficial con información pero la información parece obsoleto ya que algunos de los indicadores mencionados solo estaban disponibles en las comstackciones de prueba, ya no existen en las versiones de producción. Alguien de Oracle debería proporcionar cierta documentación actualizada sobre el G1 GC.

No G1 no es un recolector de basura predeterminado en jdk 1.7.0_02. El recolector de basura predeterminado depende de la clase de máquina. Si la máquina es de clase Servidor, el recolector de basura predeterminado es Recostackdor de rendimiento. Si la máquina es de clase Client, el recolector de basura predeterminado es Serial Collector.

De forma predeterminada, no desea realmente utilizar el recostackdor G1, ya que no es realmente mejor que los demás. Solo es bueno para fines especiales.

En aplicaciones de baja latencia es ligeramente mejor que CMS, ya que tiene un poco más corto, y tiempos de pausa más predecibles. A cambio, el rendimiento es mucho peor que CMS a cambio.

Por lo tanto, solo es bueno si la latencia es importante, pero el rendimiento no es importante en absoluto. Si ambos son importantes, entonces quédate con CMS.