Explicación detallada del principio del recolector de basura G1

1. Fondo de desarrollo del recolector de basura G1:

1. Defectos del recolector de basura CMS:

El propósito del equipo de JVM para diseñar el recopilador G1 es reemplazar el recopilador CMS, porque el recopilador CMS tiene muchos problemas en muchos escenarios y los defectos están totalmente expuestos, como se indica a continuación:

(1) El recopilador de CMS es muy sensible a los recursos de la CPU. En la etapa de concurrencia, aunque no hará que el subproceso del usuario se detenga, ocupará recursos de la CPU y hará que el programa de referencia se ralentice y el rendimiento total disminuya. El número de subprocesos de reciclaje iniciados por CMS de forma predeterminada es: (número de CPU + 3) / 4

(2) El recopilador de CMS no puede manejar la basura flotante. Dado que el subproceso del usuario aún se está ejecutando durante la fase de limpieza simultánea del CMS, se generará naturalmente nueva basura junto con la ejecución del programa. Esta parte de la basura aparece después del proceso de marcado. y se denomina "basura flotante". , CMS no puede procesarlos en esta colección, por lo que debe limpiarse en el próximo GC.

(3) Dado que se generará "basura flotante" durante la fase de recolección de basura, el recolector de CMS no puede esperar hasta que la generación anterior se llene casi por completo como otros recolectores, y necesita reservar una parte del espacio de memoria para la recolección simultánea. . Bajo la configuración predeterminada de JDK5, el colector CMS se activará cuando se utilice el 68% del espacio antiguo (JDK6 aumentó al 92%), y el porcentaje de activación también se puede aumentar a través del valor del parámetro para reducir la cantidad de memoria. reciclar y mejorar el rendimiento
-XX:CMSInitiatingOccupancyFraction. Si la memoria reservada durante la ejecución del CMS no puede satisfacer las necesidades de otros subprocesos del programa, se producirá una falla de "Falla del modo concurrente". En este momento, la máquina virtual iniciará un plan de respaldo: habilite temporalmente el recopilador Serial Old para volver a recoger la basura en la vejez, por lo que el tiempo de pausa es muy largo. Por lo tanto, si la -XX:CMSInitiatingOccupancyFractionconfiguración del parámetro es demasiado alta, conducirá fácilmente a la falla de "Falla del modo concurrente" y, en cambio, se reducirá el rendimiento.

(4) CMS es un colector implementado basado en el algoritmo "mark-clear" , que generará una gran cantidad de fragmentos de memoria discontinuos. Cuando hay demasiados fragmentos de espacio en la generación anterior, si no puede encontrar una memoria contigua lo suficientemente grande para almacenar objetos, deberá activar un GC completo con anticipación. Para resolver este problema, el recopilador de CMS proporciona un parámetro de cambio -XX:UseCMSCompactAtFullCollection, que se usa para agregar un proceso de desfragmentación después del GC completo. También puede usar el parámetro -XX:CMSFullGCBeforeCompaction para establecer cuántas veces ejecutar el GC completo sin comprimir, seguido de Hagamos un proceso de desfragmentación.

2. Características del recolector de basura G1:

El recolector G1 (Garbage First) es un nuevo recolector proporcionado por JDK7, y está designado como recolector GC oficial en JDK9. Es adecuado para servidores con "CPU multinúcleo y gran memoria". Intenta cumplir con los objetivos de tiempo de pausa de recolección de elementos no utilizados (GC) con alta probabilidad mientras logra un alto rendimiento. En comparación con el recopilador CMS, las mejoras más destacadas son:

  • Basado en el algoritmo "mark-sort" , no habrá fragmentación de la memoria después de la recopilación.
    Los tiempos de pausa se pueden controlar con mucha precisión, lo que permite la recolección de elementos no utilizados con pocas pausas sin sacrificar el rendimiento.
  • Antes de presentar el proceso de recolección de basura de G1, comprendamos brevemente el modelo de memoria y las principales estructuras de datos en G1. Estos resultados de datos son muy importantes para que entendamos el proceso de recolección de basura de G1.

En segundo lugar, el modelo de memoria del recolector de basura G1:

El colector G1 no adopta el diseño de aislamiento físico tradicional de la nueva generación y la generación anterior, sino que solo divide lógicamente la nueva generación y la generación anterior, y divide toda la memoria del montón en 2048 regiones de bloques de memoria independientes de igual tamaño. es una sección lógica A continua de memoria, el tamaño específico depende del tamaño real del montón, el control general está entre 1M - 32M, y es la N-ésima potencia de 2 (1M, 2M, 4M, 8M, 16M y 32M ), y usa Regiones diferentes para representar la nueva generación y la generación anterior. G1 ya no requiere que el mismo tipo de Regiones sean adyacentes en la memoria física, sino que se logre una continuidad lógica a través de la asignación dinámica de Regiones.

El recolector G1 rastrea la acumulación de basura en la región y recupera la región con la prioridad más alta cada vez de acuerdo con el tiempo de recolección de basura establecido, evitando la recolección de basura de toda la nueva generación o toda la generación anterior, acortando la parada del mundo. y más corto Controlable, y al mismo tiempo, se puede obtener la mayor eficiencia de recuperación en un tiempo limitado.

Nota: No hay distinción entre superviviente0 y superviviente1 en G1, solo hay uno y el tamaño se asigna dinámicamente.

A través del mecanismo de división de áreas y reciclaje de áreas prioritarias, se asegura que el recolector G1 pueda obtener la mayor eficiencia de recolección de basura en un tiempo limitado.

1. Región de partición:

inserte la descripción de la imagen aquí
El recolector de elementos no utilizados G1 divide la memoria del montón en varias regiones, y cada partición de región solo puede desempeñar una función, una de Eden, S y O, y el área en blanco representa la memoria no asignada.

Finalmente, hay un área especial H (Humongous), que se usa especialmente para almacenar objetos enormes.Si el tamaño de un objeto supera el 50% de la capacidad de la Región, G1 lo considera un objeto enorme. En otros recolectores de basura, estos objetos gigantes se asignan en la vejez de forma predeterminada, pero si se trata de un objeto gigante de corta duración, colocarlo en la vejez tendrá un impacto negativo en el recolector de basura y desencadenará GC frecuentes en la antigüedad. edad. Para resolver este problema, G1 divide un área H para almacenar objetos grandes. Si un área H no puede contener un objeto grande, entonces G1 buscará un área H continua para almacenarlo. Si no puede encontrar un área H continua, tendrá que iniciar Full GC.

2 、 conjunto de recordatorios:

Tanto en los recopiladores en serie como en los paralelos, GC escanea todo el montón para determinar si un objeto se encuentra en una ruta accesible. Sin embargo, para evitar el escaneo completo del montón al estilo STW, G1 asigna un RSet (Conjunto recordado) para cada partición, que es similar a un puntero inverso internamente, registrando las referencias de otras Regiones a la Región actual, brindando así un Gran Ventaja: al reclamar una región, no necesita realizar un análisis completo del montón, solo necesita analizar su RSet para encontrar referencias externas para determinar si los objetos a los que se hace referencia en esta partición están vivos y luego determinar la supervivencia de los objetos en esta partición, y estas referencias son una de las raíces de la marca inicial.

De hecho, no es necesario registrar todas las referencias en RSet. Si la fuente de referencia es el objeto de esta partición, entonces no es necesario registrarlas en RSet; al mismo tiempo, cada vez que G1 GC, toda la nueva generación se ser escaneado, por lo que la fuente de referencia es un objeto de la generación joven, y no necesita ser registrado en RSet; por lo tanto, al final, solo es necesario registrar la referencia de generación cruzada entre la generación anterior y la nueva generación.

3 、 Mesa de cartas:

Si un subproceso modifica la referencia dentro de la Región, debe notificar a RSet para cambiar los registros en él. Cabe señalar que si hay muchos objetos a los que se hace referencia, el colocador debe procesar cada referencia y la sobrecarga del colocador será muy alta, por lo que el recopilador G1 introduce la tabla de tarjetas para resolver este problema.

Una tabla de tarjetas divide lógicamente una región en varias áreas continuas de tamaño fijo (entre 128 y 512 bytes), y cada área se denomina tarjeta Tarjeta, por lo que Tarjeta es la granularidad más pequeña disponible en la memoria del montón. Los objetos asignados ocuparán un número de tarjetas físicamente continuas Al buscar referencias a objetos en la partición, se pueden buscar a través de la tarjeta Tarjeta (ver RSet). Cada tarjeta usa un byte para registrar si se ha modificado, y la tabla de tarjetas es una colección de estos bytes, que es una matriz de bytes, y la dirección de espacio de cada partición se identifica mediante el subíndice de la matriz de tarjetas. Por defecto no se hace referencia a cada Tarjeta. Cuando se hace referencia a un espacio de direcciones, el valor del índice de matriz correspondiente a este espacio de direcciones se marca como "0", es decir, se marca como sucio y referenciado. Además, RSet también descargue esta matriz Márquela.

Una región puede tener varios subprocesos que se modifican al mismo tiempo, por lo que RSet también puede modificarse al mismo tiempo. Para evitar conflictos, el recolector de elementos no utilizados G1 divide aún más el RSet en múltiples HashTables, y cada subproceso se modifica en su propia HashTable. En última instancia, lógicamente, un RSet es una colección de estas HashTables. La tabla hash es una forma común de implementar RSet. Su ventaja es que puede eliminar la duplicación, lo que significa que el tamaño de RS será equivalente a la cantidad de punteros modificados. En caso de que no haya duplicación, la cantidad de RS y operaciones de escritura El número es equivalente.

La Clave de HashTable es la dirección de inicio de otras Regiones, y el Valor es una colección, y los elementos que contiene son el Índice de la Tabla de Cartas.

La relación entre las primeras tres estructuras de datos es la siguiente:
inserte la descripción de la imagen aquí
La línea punteada de RS en la figura indica que RSet no es una estructura de datos separada y diferente de Card Table, sino que RS es un modelo conceptual. De hecho, Card Table es una implementación de RS.

El uso de memoria de G1 es en unidades de regiones, mientras que la asignación de objetos es en unidades de tarjetas.

4. Barrera de escritura de RSet:

Una barrera de escritura significa que cada vez que un tipo de referencia de referencia realiza una operación de escritura, se generará una barrera de escritura para interrumpir temporalmente la operación y realizar algunas acciones adicionales.

Para las barreras de escritura, es muy necesario filtrar las operaciones de escritura innecesarias, porque la sobrecarga de instrucciones de las barreras de escritura es muy costosa, lo que no solo puede acelerar la velocidad del colocador, sino también reducir la carga del recopilador. La barrera de escritura del colector G1 es complementaria al RSet, cuando se genera una barrera de escritura comprobará si el objeto al que apunta la referencia a escribir está en una Región diferente a los datos de tipo Referencia, si son diferentes, la información de referencia relevante se registrará en la referencia a través de CardTable. En el RSet correspondiente a la región donde se encuentra el objeto señalador, el RSet se puede reducir en gran medida mediante el filtrado.

(1) Cerca antes de escribir: cuando una declaración de asignación está a punto de ejecutarse, el objeto en el lado izquierdo de la ecuación modificará la referencia a otro objeto, luego la partición donde el objeto originalmente referenciado por el objeto en el lado izquierdo de la ecuación perderá una referencia, y la JVM debe estar en Antes de que la instrucción de asignación surta efecto, se registra el objeto que perdió la referencia. Pero la JVM no mantiene el RSet inmediatamente, sino que a través del procesamiento por lotes, el RSet se actualizará en el futuro.

(2) Valla posterior a la escritura: cuando se ejecuta una instrucción de asignación, el objeto del lado derecho de la ecuación obtiene una referencia al objeto del lado izquierdo y el RSet de la partición donde se encuentra el objeto del lado derecho de la ecuación. La ecuación se encuentra también debe actualizarse. Además, para reducir los gastos generales, después de que se produzca el límite posterior a la escritura, RSet no se actualizará inmediatamente, sino que también registrará el registro de actualización para el procesamiento por lotes en el futuro.

Cuando el recolector de elementos no utilizados G1 realiza la recolección de elementos no utilizados, agregar RSet al rango de enumeración del nodo raíz del GC puede garantizar que no se realice ningún análisis global y que no haya omisiones. Además, el resto de recolectores de basura generacionales que utiliza la JVM también tienen barreras de escritura, por ejemplo, cada vez que se modifique una referencia a un objeto de la generación anterior para que apunte a un objeto de la generación joven, será capturado y registrado por la barrera de escritura. Al recopilar la generación anterior, puede evitar escanear toda la generación anterior para encontrar la raíz.

La barrera de escritura del recolector de basura de G1 utiliza una estructura de búfer de registro de dos niveles:

  • conjunto global de búfer lleno: un conjunto global compartido por todos los subprocesos, que almacena la colección de búfer de registro lleno
  • búfer de registro de subprocesos: el búfer de registro propio de cada subproceso. Todos los subprocesos colocarán el registro de barrera de escritura en su propio búfer de registro primero, y cuando esté lleno, colocarán el búfer de registro en el conjunto global de búfer lleno y luego solicitarán un búfer de registro;

5 、 juego de recogida:

Collect Set (CSet) se refiere a la colección de Regiones para reciclar seleccionadas por el recolector de basura G1 en la fase de Evacuación. En cualquier recolector, todas las particiones del CSet se liberarán y los objetos supervivientes internos se transferirán a la asignación libre. espacio partición. El rendimiento suave en tiempo real de G1 se realiza a través de la selección de CSet. En correspondencia con los dos modos del algoritmo, el modo generacional completamente joven y el modo parcialmente joven, la selección de CSet se puede dividir en dos tipos:

  • Modo generacional totalmente joven: también conocido como GC joven, en este modo el CSet solo contendrá regiones jóvenes, y G1 coincide con el objetivo de tiempo real suave al ajustar la cantidad de regiones en la nueva generación;

  • Modo parcialmente joven: también conocido como GC mixto, este modo seleccionará todas las regiones jóvenes y seleccionará una parte de la región anterior, la selección de la región anterior se basará en el recuento de objetos supervivientes en la fase del ciclo de marcado y filtrar la partición con el ingreso de reciclaje más alto Agregar a CSet (se recicla la Región con la menor cantidad de objetos sobrevivientes)


-XX:G1MixedGCLiveThresholdPercentLas condiciones de acceso de CSet para las particiones candidatas de generación anterior se pueden establecer a través del umbral de actividad (85% predeterminado), interceptando así aquellos objetos con costos de recuperación enormes; al mismo tiempo, cada colección mixta puede incluir particiones candidatas de generación anterior, y el montón puede ser clasificado según CSet La proporción del tamaño total de -XX:G1OldCSetRegionThresholdPercent(10% por defecto) establece el límite superior del número.

De lo anterior se puede ver que la recolección de G1 se basa en la operación de CSet. No hay una diferencia obvia entre la recolección de generación joven y la recolección mixta. La mayor diferencia radica en las condiciones de activación de las dos colecciones.

3. El proceso de recolección de basura de G1:

G1 proporciona dos modos de GC, Young GC y Mixed GC, ambos Stop The World (STW), pero antes de hablar sobre la recolección de elementos no utilizados, presentemos la estrategia de asignación de objetos de G1.

1. Estrategia de asignación de objetos:

Cada región asignada se puede dividir en dos partes, asignada y no asignada, y el límite entre ellas se denomina parte superior. En términos generales, para asignar un objeto a una región, solo necesita aumentar el valor de top. El proceso es el siguiente:
inserte la descripción de la imagen aquí

(1) Búfer de asignación local de subprocesos Búfer de asignación local de subprocesos (TLab):

Si los objetos se asignan en un espacio compartido, entonces necesitamos usar un mecanismo de sincronización para resolver el problema de los conflictos de concurrencia Para reducir el tiempo de sincronización perdido por los conflictos de concurrencia, G1 asigna un búfer de asignación local TLAB para cada subproceso de aplicación y GC subproceso Cuando se asigna memoria de objeto, se asigna en este búfer y no hay necesidad de ninguna sincronización entre subprocesos, lo que mejora la eficiencia del GC. Pero cuando un subproceso agota su propio búfer, debe solicitar un nuevo búfer. En este momento, todavía habrá problemas de concurrencia. El recopilador G1 utiliza la operación CAS (Compate And Swap).

Obviamente, el uso de la tecnología TLAB traerá fragmentos. Por ejemplo, cuando un subproceso asigna en su propio búfer, aunque todavía queda espacio en el búfer, el objeto asignado es demasiado grande para acomodar el espacio libre. En este momento, el subproceso solo puede solicitar uno nuevo. y se desperdicia el espacio libre en el búfer original. Tanto el tamaño del búfer como la cantidad de subprocesos afectarán la cantidad de estos fragmentos.

Cada vez que se recolecta basura, cada subproceso de GC también puede ocupar exclusivamente un búfer local (GCLAB) para transferir objetos y copiar objetos supervivientes en el espacio Survivor o en el espacio de la generación anterior;

Para los objetos que se promocionan desde el espacio Eden/Survivor al espacio Survivor/antigua generación, también hay un búfer local exclusivo de GC para operaciones, que se denomina búfer local de promoción (PLAB).

(2) Asignación en el área de Eden:

Para los objetos que no se pueden asignar en el espacio TLAB, la JVM intentará asignarlos en el espacio Eden. Si el espacio Eden no puede acomodar el objeto, el espacio solo se puede asignar en la generación anterior.

(3) Asignación de área gigantesca:

Los objetos gigantescos ocuparán exclusivamente una o más particiones consecutivas, donde la primera partición se marca como Empieza enorme y las particiones consecutivas adyacentes se marcan como Continúa enorme. Dado que no puede disfrutar de la optimización que trae TLab, y necesita escanear todo el montón para determinar un espacio de memoria continuo, el costo de determinar la posición inicial de objetos enormes es muy alto. Si es posible, la aplicación debe evitar generar enormes objetos.

G1 ha realizado una optimización interna, una vez que encuentra que no hay ninguna referencia que apunte al objeto gigante, puede reciclarse directamente en el ciclo de recolección de la generación joven.

2 、 G1 joven GC:

Cuando el área de Eden está llena y la JVM no puede asignar objetos al área de Eden, se activará un GC joven de colección de generación joven de estilo STW, y los objetos sobrevivientes en el área de Eden se copiarán en el área de sobrevivientes; Los objetos en el área de sobrevivientes se copiarán de acuerdo con Los umbrales para el número de tiempos de supervivencia se promueven a PLAB, al área de sobrevivientes y a la generación anterior respectivamente; si el espacio de sobrevivientes es insuficiente, algunos datos en el área de Eden se transferirán directamente promovido al espacio de la vieja generación. Al final, los datos en el espacio de Eden están vacíos, el GC deja de funcionar y el subproceso de la aplicación continúa ejecutándose.

El GC joven también es responsable de mantener la edad (tiempos de supervivencia) del objeto y ayudar a juzgar el paradero del objeto envejecido (tenencia) cuando se promueve. El GC joven primero mantiene la suma del tamaño del objeto de promoción y la información de edad en la tabla de edad, y luego llena la capacidad de acuerdo con la tabla de edad, el tamaño del superviviente y el superviviente -XX:TargetSurvivorRatio (predeterminado 50 %), umbral máximo de permanencia - XX:MaxTenuringThreshold (predeterminado 15), calcule un umbral de tenencia apropiado y todos los objetos que excedan el umbral de tenencia serán promovidos a la generación anterior.

En este momento, debemos considerar un problema, si solo los objetos de nueva generación de GC, ¿cómo encontramos todos los objetos raíz? ¿Están todos los objetos en las raíces de la vieja generación? Tomará mucho tiempo escanear de esta manera. Entonces, necesitamos usar el RSet que presentamos anteriormente, que registra las referencias de otras regiones a la región actual. Por lo tanto, al realizar Young GC, al escanear la raíz, solo se necesita escanear esta área, en lugar de toda la edad anterior.

2.1 El proceso de recuperación detallado del joven GC:

(1) La primera etapa, exploración raíz:

La raíz se refiere al objeto al que apunta la variable estática, la variable local en la cadena de llamadas al método que se está ejecutando, etc. La referencia raíz junto con las referencias externas registradas por RSet sirven como punto de entrada para escanear objetos en vivo.

(2) En la segunda etapa, actualice RSet:

Procese las tarjetas en la cola de tarjetas sucias y actualice el RSet. Después de completar esta etapa, el RSet puede reflejar con precisión las referencias de la generación anterior a los objetos en la partición de la región donde se encuentra.

(3) La tercera etapa: procesamiento RSet:

Identifique los objetos en Eden que son señalados por los objetos de la generación anterior, y estos objetos en Eden que son señalados se consideran objetos sobrevivientes.

(4) La cuarta etapa: copia de objeto:

Los objetos sobrevivientes en el área de Eden se copiarán al área de sobrevivientes; los objetos sobrevivientes en el área de sobrevivientes se promoverán al PLAB, al área de sobrevivientes y a la vejez de acuerdo con el umbral de tiempos de supervivencia; si el espacio de sobrevivientes es no es suficiente, algunos datos en el área de Eden serán promovidos directamente al espacio de generación anterior.

(5) La quinta etapa: procesamiento de referencias:

Cuando se trata de referencias suaves, referencias débiles y referencias fantasma, los datos en el espacio de Eden eventualmente estarán vacíos y el GC dejará de funcionar, mientras que los objetos en la memoria de destino se almacenan continuamente sin fragmentación, por lo que el proceso de copia puede lograr el efecto de la organización de la memoria y reducir la fragmentación.

3, GC mixto G1:

    年轻代不断进行垃圾回收活动后,为了避免老年代的空间被耗尽。当老年代占用空间超过整堆比 IHOP 阈值 -XX:InitiatingHeapOccupancyPercent(默认45%)时,G1就会启动一次混合垃圾回收Mixed GC,Mixed GC不仅进行正常的新生代垃圾收集,同时也回收部分后台扫描线程标记的老年代分区。Mixed GC步骤主要分为两步:

(1) Marcado concurrente global (marcado concurrente global)

(2) Copiar objetos supervivientes (evacuación)

Lo que necesita atención especial aquí es que Mixed GC no es Full GC Solo cuando Mixed GC es demasiado tarde para reclamar la
región anterior, es decir, cuando los objetos en la generación anterior deben asignarse, pero se descubre que no hay suficiente espacio, se activará un GC completo en este momento

3.1 Marcaje concurrente global

Antes del reciclaje mixto, primero se realizará el marcado concurrente global En G1 GC, no es una parte necesaria de un proceso de GC, pero proporciona principalmente servicios de marcado para Mixed GC. El proceso de ejecución de la calificación concurrente global se divide en cinco pasos:

(1) Marca inicial (marca inicial, STW):

Se marcarán todos los nodos de GC Roots y los objetos directamente accesibles. Esta etapa debe detener el mundo, pero lleva poco tiempo.

El proceso de marcaje inicial está íntimamente relacionado con el GC joven. De hecho, cuando se alcanza el umbral IHOP, G1 no inicia inmediatamente un ciclo de marcado simultáneo, sino que espera a la siguiente colección de generación joven y utiliza el período STW de la colección de generación joven para completar el marcado inicial. .

(2) Exploración de la región raíz (exploración de la región raíz):

Escanee los objetos de área de generación anterior accesibles en el área de supervivencia marcada inicialmente (es decir, el área de supervivencia) y marque el objeto raíz. Esta fase se ejecuta simultáneamente con la solicitud, y el próximo GC joven de STW no puede comenzar hasta que se complete esta fase.

Debido a que RSet no registra referencias de la región joven, puede haber una situación en la que un objeto sobreviviente en la generación anterior solo sea referenciado por objetos en la generación joven. En un GC joven, estos objetos supervivientes de la generación joven se copiarán en la región superviviente, por lo que es necesario escanear estas regiones supervivientes para encontrar referencias a estos objetos que apunten a la generación anterior, como parte de la fase de marcado concurrente que escanea la raíz de la vieja generación

(3) Marcado concurrente:

Realice análisis de accesibilidad en objetos en el montón de GC Roots para encontrar objetos sobrevivientes. Este proceso puede ser interrumpido por GC joven, y las nuevas referencias (o actualizaciones de referencia) generadas durante la fase de marcado concurrente serán registradas por la barrera de escritura de SATB al mismo tiempo. , el subproceso de marcado concurrente también verificará y procesará periódicamente los registros de la lista de búfer global STAB y actualizará la información de referencia del objeto. Durante esta fase, si se descubre que todos los objetos de la región son basura, la región se recupera inmediatamente. Al mismo tiempo, durante el proceso de marcado simultáneo, se calcula la tasa de supervivencia de los objetos en cada región.

En la etapa de marcado concurrente, tenemos que entender el algoritmo de marcado de tres colores, que presentaremos a continuación.

(4) Observación (Observación, STW):

La fase de remarcado es para corregir la parte del registro de marca que ha cambiado debido a la operación continua de la aplicación durante el período de marca concurrente, que es para procesar el búfer de registro SATB restante y todas las actualizaciones, y encontrar todos los supervivientes a los que no se accedió. objetos

En el recopilador de CMS, el remarcado usa actualizaciones incrementales, mientras que G1 usa un algoritmo SATB de instantánea inicial que es más rápido que CMS
: instantánea al principio.

SATB
creará una instantánea de los objetos sobrevivientes al comienzo del marcado, para garantizar que todos los objetos basura en la fase de marcado concurrente puedan identificarse a través de instantáneas. Cuando se produce la declaración de asignación, la aplicación cambiará su gráfico de objetos, luego la JVM necesita registrar el objeto sobrescrito, por lo que la valla de escritura anterior registrará el valor en el registro o búfer de SATB antes de que cambie la referencia (cada subproceso ocupará Exclusivamente un búfer SATB, inicialmente con 256 registros de espacio). Cuando se agote el espacio, el subproceso asignará un nuevo búfer SATB para continuar usándolo y el búfer original se agregará a la lista global. Finalmente, en la etapa de marcado concurrente, el subproceso de marcado concurrente verificará y procesará periódicamente los registros de la lista de búfer global mientras marca, y luego escaneará el campo de referencia para actualizar el RSet de acuerdo con el bit de marcado del segmento de mapa de bits de marcado, corrigiendo el Error SATB
.

El búfer de registro de SATB es el mismo que el búfer de registro utilizado por la barrera de escritura de RSet, tiene una estructura de dos niveles y el mecanismo de acción es el mismo.

(5) Limpiar (Limpieza, STW):

Esta etapa es principalmente para ordenar el valor y el costo de recuperación de cada región y formular un plan de recuperación de acuerdo con el tiempo de pausa esperado del GC del usuario. (Esta etapa en realidad no realiza la recolección de basura, ni realiza una copia de los objetos sobrevivientes)

El detalle de las operaciones realizadas en la fase de limpieza es el siguiente:

① Combinación de RSet: el algoritmo heurístico definirá diferentes niveles para las particiones según la actividad y el tamaño de RSet, y las matemáticas de RSet también ayudan a encontrar referencias inútiles.

② Organice particiones en montón: identifique colecciones de particiones de generación anterior con beneficios de alta recuperación (basados ​​en objetivos de pausa y espacio libre) para colecciones mixtas;

③ Identifique todas las particiones inactivas: busque particiones sin objetos supervivientes, que se puedan recuperar directamente durante la fase de limpieza sin esperar al siguiente ciclo de recopilación.

inserte la descripción de la imagen aquí
Si no considera la operación de mantener el conjunto recordado, se puede dividir en cuatro pasos en la figura anterior (similar a CMS), en los que el marcado inicial, el marcado concurrente y el remarcado son los mismos que el colector CMS. , y solo la cuarta etapa de detección y recuperación es algo diferente.

3.2 Copiar objetos supervivientes (evacuación):

inserte la descripción de la imagen aquí

Cuando G1 inicia el marcado simultáneo global, no comenzará la recolección mixta inmediatamente. G1 esperará primero a la próxima recolección de generación joven y luego determinará el CSet para la próxima recolección mixta en la fase de recolección de gc joven

Después de completar el marcado global, G1 sabrá qué regiones antiguas tienen la mayor cantidad de basura reciclable, solo espere el momento adecuado para comenzar el reciclaje mixto, y el reciclaje mixto no solo reciclará la región joven, sino también reciclará algunas regiones antiguas (no es necesario para reciclar Todas las antiguas regiones). De acuerdo con el objetivo de pausa, es posible que G1 no pueda reciclar todas las particiones candidatas de regiones antiguas a la vez, y solo puede seleccionar varias regiones con alta prioridad para el reciclaje, por lo que G1 puede generar varias recopilaciones híbridas consecutivas y ejecución alternativa de subprocesos de aplicaciones, y estos La región seleccionada es el CSet, y el algoritmo de recuperación mixto único es exactamente el mismo que el algoritmo Young GC anterior, excepto que hay más segmentos de memoria de la generación anterior en la colección de recuperación CSet; y el segundo paso es recopilar estas regiones Los objetos supervivientes se copian en la región espacial y estas regiones recuperadas se colocan en la lista de regiones libres.

G1 calculará la cantidad de particiones agregadas al CSet cada vez y la cantidad de colecciones mixtas, y en la última colección de generación joven y la siguiente colección mixta, G1 determinará el conjunto de particiones (Elegir CSet) que se agregará al CSet la próxima vez, y se determina si terminar el ciclo de recolección híbrida.

(1) Después de que finalice el marcado simultáneo, las regiones que son 100 % basura en la generación anterior se reciclarán directamente, y las regiones que solo son parcialmente basura se dividirán en 8 reciclajes (se puede establecer mediante -XX:G1MixedGCCountTarget, el el umbral predeterminado es 8), por lo que el conjunto de recuperación (CSet) de Mixed GC incluye una octava parte del segmento de memoria de vejez, el segmento de memoria del área Eden y el segmento de memoria del área Survivor.

(2) Dado que los segmentos de memoria de la generación anterior se reciclan 8 veces de forma predeterminada, G1 dará prioridad al reciclaje de los segmentos de memoria con más basura. Cuanto mayor sea la proporción de basura en el segmento de memoria, más se reciclará primero. Y un umbral determina si el segmento de memoria se reclama -XX:G1MixedGCLiveThresholdPercent, el valor predeterminado es 65 %, lo que significa que la proporción de elementos no utilizados en el segmento de memoria debe alcanzar el 65 % antes de que se recupere. Si la proporción de basura es demasiado baja, significa que la proporción de objetos supervivientes es alta y llevará más tiempo copiarlos.

(3) No es necesario realizar el reciclaje mixto 8 veces. Hay un umbral -XX:G1HeapWastePercent, el valor predeterminado es 10 %, lo que significa que se permite desperdiciar el 10 % de toda la memoria del montón, lo que significa que si se encuentra que la basura reciclable ocupa la memoria del montón. Si la proporción es inferior al 10 %, no se realizará una recuperación mixta, porque el GC tardará mucho tiempo, pero la memoria recuperada es muy poca.

inserte la descripción de la imagen aquí
Resumen del proceso de recolección de basura de G1: Young CG y Mixed GC son las principales actividades de G1 para recuperar espacio. Cuando la aplicación comienza a ejecutarse, el espacio libre de la memoria del montón sigue siendo relativamente grande, y la recopilación de la generación joven solo se activará cuando la generación joven esté llena; a medida que crezca la memoria de la generación anterior, cuando el umbral IHOP sea alcanzado (la proporción de la generación anterior a todo el montón, el valor predeterminado es 45 % -XX:InitiatingHeapOccupancyPercent), G1 comienza a prepararse para recopilar el espacio de la generación anterior. Primero pase por ciclos de marcado simultáneos, identificando particiones de generación anterior de alto rendimiento. Pero entonces G1 no iniciará una colección mixta de inmediato, sino que dejará que el subproceso de la aplicación se ejecute durante un tiempo, a la espera de desencadenar una colección de generación joven. En este STW, G1 comenzará a resolver el ciclo de colección mixta. A continuación, deje que el subproceso de la aplicación se ejecute de nuevo. Durante las próximas recopilaciones de generaciones jóvenes, se agregarán particiones de generaciones antiguas al CSet, lo que desencadena recopilaciones mixtas. Estas recopilaciones mixtas consecutivas se denominan recopilaciones mixtas.

4, GC completo:

    当 G1 无法在堆空间中申请新的分区时,G1便会触发担保机制,执行一次STW式的、单线程的 Full GC,Full GC会对整堆做标记清除和压缩,最后将只包含纯粹的存活对象。参数-XX:G1ReservePercent(默认10%)可以保留空间,来应对晋升模式下的异常情况,最大占用整堆50%,更大也无意义。

G1 activará Full GC en los siguientes escenarios y registrará el espacio agotado y la falla de evacuación en el registro:

(1) Al copiar objetos supervivientes de la partición de la generación joven, es imposible encontrar una partición libre disponible
(2) Al transferir objetos supervivientes de la partición de la generación anterior, es imposible encontrar una partición libre disponible
(3) Al asignar grandes objetos, no es posible encontrar suficientes particiones libres en la generación anterior. Particionamiento continuo
Dado que las ocasiones de aplicación de G1 a menudo tienen memoria de almacenamiento dinámico relativamente grande, el costo de recopilación de Full GC es muy alto y se debe evitar la ocurrencia de Full GC.

5. Algoritmo de marcado de tres colores:

El algoritmo de marcado de tres colores es un algoritmo importante en la fase de recopilación concurrente. Es un método útil para describir el seguimiento del recopilador y se puede utilizar para deducir la exactitud del recopilador. Primero, dividimos los objetos en tres tipos.

Negro: el objeto raíz o el objeto y sus subobjetos han sido escaneados
Gris: el objeto mismo ha sido escaneado, pero los subobjetos del objeto no han sido escaneados
Blanco: el objeto no escaneado, después de que todos los objetos hayan sido escaneados , eventualmente será Los blancos son objetos inalcanzables, es decir, objetos basura.
A continuación, usaremos un conjunto de diagramas de evolución para profundizar nuestra comprensión del algoritmo de marcado de tres colores. Cuando el GC comience a escanear objetos, escanee los objetos según a los siguientes pasos:

5.1 El proceso normal del algoritmo de marcado de tres colores:

(1) El objeto raíz se configura en negro y los subobjetos se configuran en gris:
inserte la descripción de la imagen aquí
(2) Continúe desplazándose desde gris y configure los objetos que han escaneado subobjetos en negro.
inserte la descripción de la imagen aquí
(3) Después de atravesar todos los objetos alcanzables, todos los objetos alcanzables se vuelven negros. Los objetos inalcanzables son blancos y deben limpiarse.
inserte la descripción de la imagen aquí

5.2 Anomalías del algoritmo de marcado de tres colores:

Si la aplicación se está ejecutando durante el proceso de marcado, el puntero del objeto puede cambiar. En este caso, nos encontraremos con un problema: el problema de la pérdida del objeto. Veamos la siguiente situación, cuando el recolector de basura analiza la siguiente situación: En
inserte la descripción de la imagen aquí
este momento, la aplicación realiza las siguientes operaciones:

A.c=C
B.c=null

De esta forma, el diagrama de estado del objeto queda así:
inserte la descripción de la imagen aquí
En este momento, cuando el recolector de basura marque y escanee nuevamente, se verá así:

inserte la descripción de la imagen aquí
Obviamente, C es blanco en este momento, lo que se considera basura y debe limpiarse, lo que obviamente no es razonable. Entonces, ¿cómo nos aseguramos de que los objetos marcados por GC no se pierdan cuando se ejecuta la aplicación? Hay dos formas posibles:

Registrar objetos al insertar y
registrar objetos al eliminar.
Esto corresponde a dos implementaciones diferentes de CMS y G1:

(1) CMS utiliza actualización incremental (Actualización incremental): siempre que se encuentre una referencia a un objeto blanco asignada a un campo de un objeto negro en la barrera de escritura, el objeto blanco se volverá gris, es decir, Grabe cuando se inserte.

(2) G1 usa el método STAB (snapshot-at-the-beginning): graba todos los objetos al borrarlos, consta de tres pasos:

① Genere una instantánea del objeto sobreviviente al comenzar a marcar
② Cuando se marca simultáneamente, todos los objetos modificados se ponen en cola (en la barrera de escritura, todos los objetos a los que apuntan las referencias antiguas se vuelven no blancos) ③ Puede existir
Basura gratuita, se recolectará a continuación tiempo

4. Optimización de parámetros

Lo anterior introduce brevemente el principio de funcionamiento de G1. Después de conocer el principio, podemos optimizar mejor la operación del programa en el proceso de usar G1 en combinación con la configuración de algunos parámetros comunes.

-XX:MaxGCPauseMillis
Tiempo máximo de pausa del GC, predeterminado 200 ms. Este es un objetivo suave. G1 hará todo lo posible para lograrlo. Si no se puede lograr, se autoajustará gradualmente.

Para Young GC, la cantidad de áreas de Eden se reducirá gradualmente y, si se reduce el espacio de Eden, el tiempo de procesamiento de Young GC se reducirá en consecuencia.

Para Mixed GC, G1 ajustará la proporción de Cset cada vez, el máximo predeterminado es 10%. Por supuesto, si el número de Csets seleccionados cada vez es menor, el número de Mixed GC que se experimentará aumentará en consecuencia.

Cset
Cuando se reduce el espacio total de Eden, Young GC se activará con más frecuencia y la frecuencia de ejecución de Mixed GC se acelerará, porque Mixed GC es activado por Young GC, o se puede decir que se ejecuta al mismo tiempo. El GC frecuente afectará el rendimiento de la aplicación. El tiempo de recuperación de cada GC mixto es demasiado corto y la cantidad de basura recolectada es demasiado pequeña. Tal vez la velocidad final de limpieza de basura del GC no pueda seguir el ritmo de la aplicación. lo que puede causar un GC completo en serie, que debe evitarse.

Por lo tanto, el tiempo de pausa no debe establecerse lo más pequeño posible. Por supuesto, no puede establecerse demasiado grande. En cambio, espere que G1 lo procese lo antes posible. Esto puede resultar en menos activaciones de GC mixto después de todas las marcas simultáneas, pero cada Cuanto mayor sea el tiempo, mayor será el tiempo de STW y el impacto más obvio en la aplicación.

-XX:G1NewSizePercentHay dos valores numéricos para el -XX:G1MaxNewSizePercent
índice de generación joven, el límite inferior: -XX:G1NewSizePercent, el valor predeterminado es 5 %, el límite superior: -XX:G1MaxNewSizePercent, el valor predeterminado es 60 %.

G1 ajustará dinámicamente el tamaño de la nueva generación, principalmente el número de Eden Regions, de acuerdo con la situación real de GC (principalmente el tiempo de pausa). Es mejor tener un espacio Eden más grande, porque la frecuencia de Young GC es más alta, y un espacio Eden grande puede reducir el número de ocurrencias de Young GC. Pero al mismo tiempo, también es necesario equilibrar las regiones de la nueva generación y la vieja generación en el GC Mixto Si el Edén es grande, no queda mucho espacio para que la vieja generación recicle, lo que eventualmente puede conducir a un GC completo.

Por supuesto, G1 aún puede establecer un tamaño de generación joven fijo (parámetros -XX: NewRatio, -Xmn), pero pausar el objetivo al mismo tiempo perderá su significado.

-XX:G1MixedGCLiveThresholdPercent
Especifique el umbral de la relación de espacio habitable de la Región incluida en el Cset, y el valor predeterminado es 85%. En la fase de marcado concurrente global, si la relación espacial de los objetos supervivientes en una Región es inferior a este valor, puede incluirse en el Cset.

Este valor afecta directamente el área que Mixed GC elige reciclar. Cuando encuentre que el tiempo de GC es largo, puede intentar bajar este umbral e intentar dar prioridad a la Región con una alta proporción de recolección de basura. Sin embargo, esto puede también conducen a una recolección de basura incompleta Eventualmente se activa Full GC.

-XX:InitiatingHeapOccupancyPercent
Especifica la proporción de uso de la generación anterior que activa el marcado simultáneo global. El valor predeterminado es 45 %, es decir, la generación anterior representa más del 45 % del almacenamiento dinámico.

Si la tasa de uso de la generación anterior aún supera el 45 % después de que finaliza el GC mixto, el proceso de marcado simultáneo global se activará nuevamente, lo que generará GC de generación anterior frecuentes y afectará el rendimiento de la aplicación. Al mismo tiempo, no hay mucho espacio en la generación anterior, y el espacio recuperado por Mixed GC debe ser relativamente pequeño. Si este valor es demasiado alto, es fácil provocar el fracaso de la promoción de la generación joven y activar el GC completo, por lo que se requieren múltiples pruebas de ajuste.

5. Desventajas del colector G1:

(1) Si el tiempo de pausa es demasiado corto, puede hacer que cada colección de reciclaje seleccionada ocupe solo una pequeña parte de la memoria del montón, y la velocidad de recolección del recolector dejará de alcanzar gradualmente la velocidad de distribución del asignador. lo que hará que la basura se acumule lentamente y, finalmente, hará que el espacio de almacenamiento dinámico se llene, lo que activará el GC completo y degradará el rendimiento.

(2) G1 es más alto que CMS tanto en el uso de memoria generado por la recolección de elementos no utilizados como en la carga de ejecución adicional cuando el programa se está ejecutando.

(3) CMS tiene una alta probabilidad de G1 en aplicaciones de memoria pequeña. Por lo tanto, el colector CMS se usa en el caso de memoria pequeña, y el colector G1 se puede usar en el caso de memoria grande (el colector G1 tiene más de 6 GB)

Artículo de referencia:
https://blog.csdn.net/a745233700/article/details/121724998?spm=1001.2014.3001.5502

Supongo que te gusta

Origin blog.csdn.net/adaizzz/article/details/130061466
Recomendado
Clasificación