[Comprensión profunda de JVM] 6. Algoritmo de GC: cómo encontrar basura + limpiar basura + modelo de generación de memoria JVM + recolector de basura común [entrevista esencial]

 Publicación anterior: [Conocimiento profundo de JVM] 5. Áreas de datos en tiempo de ejecución + instrucciones comunes [requeridas para entrevistas]

1. Conocimientos básicos de GC

1. La diferencia entre JAVA y C ++ GC

1 、 java

  • Basura de procesamiento de GC

  • Alta eficiencia de desarrollo, baja eficiencia de ejecución.

2 、 C ++

  • Eliminación de desechos de manos

  • Olvidé reciclar basura

    • Pérdida de memoria

  • Reciclado muchas veces

    • Acceso no autorizado

  • Baja eficiencia de desarrollo, alta eficiencia de ejecución.

2. Cómo localizar la basura.

1, RC: recuento de referencia recuento de referencia

  • Principio de algoritmo: agregue un contador de referencia a un objeto. Siempre que una referencia a él, el valor del contador se incrementa en 1; cuando una referencia expira, el valor del contador se reduce en 1; cuando el contador de referencia es 0, significa que el el objeto ya no se utiliza, se puede reciclar.
  • Aplicación: Microsoft COM / ActionScript3 / Python
  • Ventajas: simple de implementar, alta eficiencia de juicio, generalmente un buen algoritmo.
  • Desventaja: Es difícil resolver el problema de las referencias circulares. El cuerpo del bucle es basura pero sus referencias no son 0

2. RS: algoritmo de búsqueda de raíz accesible a la raíz

Algoritmo de accesibilidad de raíz
  • Principio del algoritmo: use el objeto llamado "GC Roots" como punto de partida para buscar hacia abajo. La ruta tomada por la búsqueda se convierte en una cadena de referencia. Cuando un objeto es inalcanzable para GC Roots, significa que el objeto ya no se usa y puede ser reciclado.
  • Aplicación: Java / C # / Lisp
  • Ventajas: puede resolver el problema de las referencias circulares.
  • Insuficiencia: el algoritmo es un poco complicado
  • Objeto raíz: raíces GC (recuerde que es importante)
    • Variable de pila de subprocesos
    • Variable estática
    • Piscina constante
    • Puntero JNI: el objeto al que hace referencia C / C ++

3. Algoritmos GC para la eliminación de basura

  • Marca-barrido (marca-barrido)

  • Proceso de copiar

  • Mark-Compact (compresión de marcas)

1. Barrido de marcas (borrado de marcas)

 

  • Primero encuentre útil, luego encuentre inútil, luego marque, luego borre

  • Características:

    • 1. El algoritmo es relativamente simple y la eficiencia es mayor cuando hay más objetos supervivientes.

    • 2. Se requieren dos escaneos (el primer paso es encontrar esos objetos útiles y el segundo paso es encontrar y eliminar los objetos inútiles), por lo que la eficiencia es relativamente baja y es fácil generar fragmentos (los que son despejados no están comprimidos ni limpios, por lo que habrá muchos vacíos)

2. Copiar

 

 

  • Divide la memoria en dos y copia las útiles a la mitad de la memoria, una vez completadas todas las copias, se borra la otra mitad de los objetos inútiles.

  • Encuentre algunos útiles, luego copie los útiles en otros lugares y luego elimine todos los objetos inútiles después de copiarlos.

  • Características:

    • 1.Es adecuado para la situación en la que hay pocos objetos supervivientes, solo se escanea una vez, se mejora la eficiencia y no hay fragmentación

    • 2. Se desperdicia espacio Mover y copiar objetos requiere ajustar las referencias de los objetos.

3. Mark-Compact (compresión de marcas)

 

 

  • Primero encuentre objetos útiles y luego muévase al frente, deje que todos los objetos útiles vayan a una esquina, y el resto son objetos inútiles, elimínelos todos

  • Características:

    • 1. Escanear dos veces requiere mover el objeto y la eficiencia es baja.

    • 2. Sin fragmentación, asignación conveniente de objetos y sin reducción a la mitad de la memoria.

4. Modelo de generación de memoria JVM (utilizado para el algoritmo de recolección de basura generacional)

 

Un objeto está primero en la pila, no cabe, y luego va al área del Edén. La recolección de basura ingresa al área de sobreviviente1 (área de sobreviviente o desde) y luego la recicla en el área de sobreviviente2. Después de múltiples recolecciones de basura, ingresa al área Vieja .

Nota: GC:

  • MinorGC / YGC: se activa cuando se agota el espacio de la generación joven
  • MajorGC / FullGC: se activa cuando la generación anterior no puede seguir asignando espacio, la nueva generación, los colegas de la generación anterior reciclan
  • -Xmn: -X: parámetros no estándar. m: Memoria n: nuevo
  • -Xms: s: valor mínimo
  • -Xmx: x: máximo

  1. Modelo utilizado por algunos recolectores de basura

    Todos los GC excepto Epsilon ZGC Shenandoah usan el modelo de generación lógica

    G1 es la generación lógica y la generación física no

    Además, no solo generación lógica, sino también generación física

  2. Espacio en pila ( nueva generación + vieja generación ) + generación permanente (1.7) Generación permanente / área de metadatos (1.8) Metaspace

    1. Almacenamiento de metadatos de generación permanente: -Clase, información recopilada del método, información compilada del código y bytecode, etc.
    2. La generación permanente debe especificar el límite de tamaño (es fácil de desbordar, esto no se puede cambiar), los metadatos se pueden configurar o no, y no hay límite superior (limitado por la memoria física)
    3. Constante de cadena 1,7-generación permanente, -> 1,8-montón
    4. MethodArea (realización concreta de 1.7 Perm Generation / Metaspace (1.8) Metaspace ) concepto lógico-generación permanente, metadatos
  3. Cenozoico = Edén + 2 áreas de supervivientes 

    1. Después de que YGC reclame, la mayoría de los objetos serán recuperados y entrarán en s0 con vida.
    2. YGC de nuevo, el objeto viviente eden + s0 -> s1
    3. YGC de nuevo, eden + s1 -> s0
    4. Edad suficiente -> vejez (15 CMS 6)
    5. No cabe en el área s -> vejez
  4. Vejez

    1. Intransigente
    2. La vejez está llena de FGC Full GC
  5. Ajuste de GC (generación)

    1. Minimizar FGC
    2. MinorGC = YGC
    3. MajorGC = FGC
  6. Edad dinámica: (no importante)  https://www.jianshu.com/p/989d3b06a49d

  7. Garantía de asignación: (no es importante) Durante YGC (young gc), el área de sobrevivientes no tiene suficiente espacio. La garantía de espacio va directamente a la vejez. Referencia: https://cloud.tencent.com/developer/article/1082730

  8. Diagrama del proceso de asignación de objetos: Secuencia de ejecución de la recolección de basura: TLAB: asignación local de subprocesos.

Diagrama del proceso de asignación de objetos

 

Sólo entender:

 Eficiencia de verificación de código:

/**
 * 减号代表去掉属性
 * -XX:-DoEscapeAnalysis 去掉逃逸分析
 * -XX:-EliminateAllocations 去掉标量替换
 * -XX:-UseTLAB 去掉线程本地分配TLAB
 * -Xlog:c5_gc*
 * 逃逸分析 标量替换 线程专有对象分配
 */
public class TestTLAB {
    //User u;
    class User {
        int id;
        String name;

        public User(int id, String name) {
            this.id = id;
            this.name = name;
        }
    }

    void alloc(int i) {
        // 无逃逸
        new User(i, "name " + i);
    }

    public static void main(String[] args) {
        TestTLAB t = new TestTLAB();
        long start = System.currentTimeMillis();
        for (int i = 0; i < 1000_0000; i++) t.alloc(i);
        long end = System.currentTimeMillis();
        System.out.println(end - start);

        //for(;;);
    }
}

Funcionamiento normal: 400

 Modificar operación de parámetros: 800

Notas:

  • Eden area + S1 -> S2 más del 50% se perderá en el área Old como se muestra arriba.

Argumentación: (consulte si comprende:  https://www.jianshu.com/p/989d3b06a49d )

uint ageTable::compute_tenuring_threshold(size_t survivor_capacity) {
    //survivor_capacity是survivor空间的大小
  size_t desired_survivor_size = (size_t)((((double) survivor_capacity)*TargetSurvivorRatio)/100);
  size_t total = 0;
  uint age = 1;
  while (age < table_size) {
    total += sizes[age];//sizes数组是每个年龄段对象大小
    if (total > desired_survivor_size) break;
    age++;
  }
  uint result = age < MaxTenuringThreshold ? age : MaxTenuringThreshold;
    ...
}

Extraje el código para calcular la edad de promoción. Echemos un vistazo al cálculo de la edad dinámica. Hay un valor TargetSurvivorRatio en el código.

-XX: Tasa de
supervivencia objetivo TargetSurvivorRatio , el valor predeterminado es 50%

  1. Calcule un valor esperado a través de esta relación, tamaño_de_superviviente_deseado.
  2. Luego, use un contador de totales para acumular el tamaño total de cada grupo de edad.
  3. Deténgase cuando el total sea mayor que deseado_survivor_size.
  4. Luego compare la edad actual y MaxTenuringThreshold para encontrar el valor mínimo como resultado

La representación general es que la edad se acumula de joven a mayor, y cuando se agrega un determinado grupo de edad, cuando la suma acumulada excede el área de sobrevivientes * TargetSurvivorRatio, se promoverá de los objetos de edad en este grupo de edad.

5. Recolectores de basura comunes

Notas:

  • 1-4: Todas son generaciones lógicamente,
  • 5-6: No hay lógica generacional.
  • 10: se utiliza para depurar.
  • Serie se refiere a la serie de un solo subproceso,
  • Paralelo se refiere a subprocesos múltiples.  
  • Combinaciones comunes: Serial + Serial Old; Parallel Scavenge + Parallel Old (este es el valor predeterminado si no hay sintonización en muchas líneas ahora); la combinación ParNew + CMS se muestra en la línea de puntos arriba.
  • CMS

     

  1. JDK nació, Serial siguió para mejorar la eficiencia y PS nació. Para cooperar con CMS, nació PN. CMS se introdujo en la versión posterior de 1.4. CMS es un hito GC que abrió el proceso de reciclaje concurrente. Sin embargo , CMS tiene muchos problemas, por lo que cualquier versión de A JDK tiene como valor predeterminado la recolección de basura concurrente de CMS porque no se puede tolerar STW
  2. El reciclaje en serie en la generación joven de CPU serie única es el más eficiente, y la máquina virtual es el recolector de basura predeterminado en el modo Cliente. punto seguro ( punto seguro)  stop-the-world (STW) (parada del hilo) STW en el punto seguro. Ahora se usa con poca frecuencia
    De serie

     

  3. PS (Parallel Scavenge) La variante de reciclaje paralelo de nueva generación de Parallel Scavenge se utiliza con CMS
    Carroñero paralelo

     

  4. La generación joven de ParNew coopera con la recuperación paralela de CMS. El tiempo de respuesta de PN tiene prioridad. Con CMS, el rendimiento de PS tiene prioridad.
    Paralelo nuevo

     

  5. SerialOld 
    Serial Viejo
  6. ParaleloAntiguo
  7. ConcurrentMarkSweep es concurrente en la vejez. La recolección de basura y las aplicaciones se ejecutan al mismo tiempo, lo que reduce el tiempo de STW (200 ms). Hay muchos problemas con CMS, por lo que no hay una versión predeterminada para CMS. Solo puede especificar manualmente que CMS es MarkSweep. Cuando la fragmentación alcanza un cierto nivel, cuando los objetos asignados en la antigüedad de CMS no se pueden asignar, use SerialOld para reciclar la antigüedad. Imagine: PS + PO -> agregar memoria para recolector de basura -> PN + CMS + SerialOld (unas pocas horas -Varios días de STW) Docenas de memoria G, reciclaje de un solo subproceso -> G1 + FGC Docenas de G -> Servidor de memoria T Algoritmo ZGC: marca de tres colores + Actualización incremental
  8. Algoritmo G1 (10ms): marca de tres colores + SATB
  9. ZGC (1ms) PK C ++ 算法 : ColoredPointers + LoadBarrier
  10. Shenandoah 算法 : ColoredPointers + WriteBarrier
  11. Eplison
  12. Lectura ampliada sobre la diferencia entre PS y PN: ▪ https://docs.oracle.com/en/java/javase/13/gctuning/ergonomics.html#GUID-3D0BB91E-9BFF-4EBB-B523-14493A860E73
  13. La relación entre el recolector de basura y el tamaño de la memoria
    1. Docenas de megabytes en serie
    2. PD: cientos de megabytes, unos pocos G
    3. CMS - 20G
    4. G1-cientos de G
    5. ZGC - 4T - 16T (JDK13)
  14. CMS
    1. Desventajas:

1.8 La recolección de basura predeterminada: PS + ParallelOld

Configuración de parámetros de combinación de recolector de basura común: (1.8)

  • -XX: + UseSerialGC = Serie nueva (DefNew) + Serie antigua

    • Pequeño programa. No será esta opción por defecto, HotSpot seleccionará automáticamente el colector según el cálculo y la configuración y la versión de JDK
  • -XX: + UseParNewGC = ParNew + SerialOld

  • -XX: + UseConc (urrent) MarkSweepGC = ParNew + CMS + Serial Old

  • -XX: + UseParallelGC = Parallel Scavenge + Parallel Old (1.8 默认) 【PS + SerialOld】

  • -XX: + UseParallelOldGC = Parallel Scavenge + Parallel Old

  • -XX: + UseG1GC = G1

  • El método de vista GC predeterminado no se encuentra en Linux, pero UseParallelGC se imprimirá en Windows 

    • java + XX: + PrintCommandLineFlags -version
    • Distinguir por registro de GC
  • ¿Cuál es exactamente el recolector de basura predeterminado de la versión 1.8 en Linux?

    • 1.8.0_181 Por defecto (no visible) Copiar MarkCompact
    • 1.8.0_222 PS + PO predeterminado

Siguiente: [Comprensión profunda de JVM] 8. Ajuste de combate real de JVM + uso de combate real de arthas + uso de combate real de jvisualvm + algoritmo GC + ajuste de JVM cómo localizar problemas + resolución de problemas en línea + errores corregidos para errores pequeños sin detener el servicio + CMS + G1 + parámetros esenciales comunes [entrevista]

Supongo que te gusta

Origin blog.csdn.net/zw764987243/article/details/109533242
Recomendado
Clasificación