Varios recolectores de basura de uso común --- máquina virtual Java (texto largo de 5,000 palabras, muy recomendado)


1. Introducción

He introducido varios algoritmos para determinar si un objeto está "muerto" y cómo recolectar objetos "basura" Ahora deberíamos echar un vistazo a varios recolectores de basura clásicos que los ponen en práctica.

Lo que se explica aquí es que el recolector de basura se divide en

  • Minor GC (para la nueva generación): Serial, ParNew, Parallel Scavenge
  • Major GC (para la vejez): CMS (Concurrent Mark Sweep) , Serial Old, Parallel Old
  • GC mixto: G1 (basura primero)

Y tienen su propia combinación, y el diagrama de combinación es el siguiente:

Inserte la descripción de la imagen aquí

Pero la combinación de Serial + CMS y ParNew + Serial Old se ha abandonado en JDK9 . CMS y G1 son los puntos clave de nuestro entendimiento.

Más adelante, escucharemos acerca de recolectores "concurrentes" y "paralelos". Aquí, "concurrencia" y "paralelo" pueden entenderse como en el contexto de discutir recolectores de basura:

  • Paralelo (Paralelo): Paralelo describe la relación entre varios subprocesos del recolector de basura, lo que indica que hay varios subprocesos de este tipo trabajando juntos al mismo tiempo y, por lo general, el subproceso del usuario en este momento está en un estado de espera por defecto. En este momento en el JVM Sólo funciona el recolector de basura, lo que significa "Detener el mundo" para el usuario.
  • Concurrente: la simultaneidad aquí describe la relación entre el recolector de basura y el subproceso del usuario. Significa que el subproceso del usuario y el subproceso del recolector están trabajando al mismo tiempo. Dado que el subproceso del usuario todavía se está ejecutando, el programa aún puede responder a las solicitudes de servicio Sin embargo, el subproceso del recolector de basura ocupa una cierta cantidad de recursos del sistema, por lo que el rendimiento de la aplicación se verá afectado hasta cierto punto.

Métricas para medir GC

Hay tres indicadores para medir la calidad de un GC: huella de memoria (huella) , rendimiento (rendimiento) y latencia (latencia) . Estos tres constituyen un triángulo imposible. El rendimiento general de los tres es bueno ya que el progreso de la tecnología mejorará y mejor. Pero es imposible alcanzar casi la perfección en los tres aspectos. Un buen GC por lo general solo puede lograr dos de ellos al mismo tiempo.

  • Huella de memoria: el tamaño del espacio de memoria que ocupará el subproceso GC cuando se esté ejecutando
  • Rendimiento: la relación entre el tiempo que el procesador dedica a ejecutar el código de usuario y el tiempo total del procesador. Si se expresa mediante una fórmula, es: tiempo de ejecución del código de usuario / (tiempo de ejecución del código de usuario + tiempo de ejecución de la recolección de basura)
  • Retraso: El retraso se debe a que el hilo del usuario debe suspenderse por un período de tiempo (Stop The World) durante el proceso de GC. El tiempo durante el cual el hilo del usuario está suspendido es el retraso.

Pero la importancia del retraso es cada vez más reconocida por todos . Porque con la mejora y el progreso del hardware informático, podemos tolerar cada vez más que GC ocupe un poco más de espacio. También podemos aceptar sacrificar una cierta cantidad de eficiencia (rendimiento ) a cambio de una mejor experiencia del usuario. En pocas palabras, el uso de la memoria y el rendimiento se pueden solucionar gastando dinero en hardware. Además, Internet es una industria de servicios hasta cierto punto y debe complacer a los usuarios. Los usuarios no Tu servidor no es eficiente, solo se preocupa por la experiencia del usuario que este sitio web le brinda, y la latencia es una experiencia de usuario muy importante.

2.G menor (GC de nueva generación)

Los siguientes tipos de GC menor se basan en el algoritmo de marca-copia.

  • Serial GC (el GC menor más antiguo y básico)
  • ParNew GC (enfoque en reducir el tiempo de respuesta)
  • Parallel Scavenge (enfoque en mejorar el rendimiento)

1. GC en serie (GC menor)

Serial GC es el GC más básico y más antiguo. Antes de JDK1.3, era la única opción para la nueva generación de GC de máquina virtual. Serial es un recopilador de un solo subproceso. Un solo subproceso aquí tiene dos significados:

  1. serial solo usará un hilo de colección
  2. Cuando el serial está realizando la recolección de basura, otros subprocesos de trabajo deben suspender todo el trabajo en cuestión hasta que el serial complete la recolección de basura. Eso es "Stop The World".

Diagrama de funcionamiento del GC antiguo en serie / en serie:

Inserte la descripción de la imagen aquí

Se puede esperar que "Stop The World" sea una experiencia terrible para los usuarios. Imagine que cuando está viendo un video, de repente el reproductor de video deja de reproducirse inmediatamente. No puede realizar ninguna operación en la computadora porque Serial está en Realización GC. Es realmente porque brinda una mala experiencia a los usuarios. Desde JDK1.3, hasta el actual JDK14, el equipo de desarrollo de máquinas virtuales HotSpot ha hecho muchos esfuerzos para reducir este "Stop The World".

Pero esto no significa que SerialGC sea el primero en aparecer y no tenga ningún efecto en la actualidad. De hecho, sigue siendo el recién nacido predeterminado de la máquina virtual HotSpot en ** el lado del cliente (pero el campo principal de Java es el lado del servidor) * Generación GC: para equipos con menos núcleos y recursos de memoria limitados, debido a que no hay una sobrecarga de interacción de subprocesos, Serial que se concentra en GC puede lograr una mayor eficiencia.

2.ParNew GC (GC menor)

ParNewGC en realidad puede considerarse como una versión paralela de múltiples subprocesos de SerialGC . Excepto por el uso de múltiples subprocesos para la recolección de basura al mismo tiempo. No hay mucha diferencia entre ParNew y Serial. Aunque no parece tener puntos brillantes , pero antes de JDK7, es la primera opción de muchas máquinas virtuales del lado del servidor para la nueva generación de GC. Pero lo curioso es que se ha convertido en la elección de muchas personas, no por ellos mismos, sino por el liderazgo ( CMS). Presentaremos CMS más adelante.

Diagrama esquemático de ParNewGC:

Inserte la descripción de la imagen aquí

Antes de que saliera G1, se puede decir que CMS es el GC de vieja generación más adecuado en el lado del servidor, y el GC de nueva generación que se puede combinar con él es solo Serial y ParNew. Parallel Scavenge no se puede combinar con CMS para algunos Pero luego, con la aparición de G1, reemplazó gradualmente a la CMS.

3.Recolección paralela (GC menor)

Parallel Scavenge también es un GC de nueva generación. Parallel Scavenge y ParNew GC son similares en muchas características en la superficie, pero el punto más importante es que se enfocan en diferentes niveles. Los recolectores como ParNew y CMS se enfocan principalmente en acortar. Tiempo de pausa , y Parallel Scavenge y su antiguo GC coincidente con Parallel Old GC se centran en mejorar el rendimiento ... El diagrama esquemático de Parallel Scave GC se proporcionará junto con el siguiente Parallel Old GC

3.Grupo principal (GC antiguo)

Los siguientes GC principales se basan en el algoritmo de copia de marca, excepto que CMS utiliza el algoritmo de barrido de marca.

  • Paralelo Viejo
  • Serie antigua
  • CMS

1 GC antiguo paralelo

Parallel Old GC es la versión anterior de Parallel Scavenge, y también es compatible con la recopilación en paralelo de múltiples subprocesos. En escenarios donde el rendimiento es importante, a menudo se usa la combinación de Parallel Scavenge + Parallel Old. Parallel Old + Parallel Scavenge se usa en conjunto:

Inserte la descripción de la imagen aquí

2 serie antigua

Serial Old es la versión antigua de Serial GC. Sus funciones se encuentran principalmente en dos aspectos:

  • Antes de la aparición de Parallel Old, se utilizó como la vejez de Parallel Scavenge
  • Como alternativa después del error Concurrent Mode Failure en el recopilador CMS.

3. ¡¡¡Enfoque CMS (barrido de marca concurrente) !!!

CMS GC es un recopilador que tiene como objetivo obtener el menor tiempo de pausa de recuperación. Las páginas web actuales de Internet prestan mucha atención a la velocidad de respuesta de la página web para mejorar la experiencia interactiva del usuario. Por lo tanto, CMS satisface perfectamente las necesidades de dichas aplicaciones. Durante mucho tiempo, fue la primera opción para el antiguo GC en el lado del servidor (hasta la aparición de G1).

Y por su nombre, se puede ver que es concurrente y se basa en el algoritmo de barrido de marcas . Echemos un vistazo más de cerca al CMS.

3.1 Proceso de implementación de CMS

Inserte la descripción de la imagen aquí

  1. Marca inicial
  2. Marca concurrente
  3. Observación
  4. Barrido concurrente

En primer lugar, se puede ver en el diagrama esquemático y el nombre que el hilo del usuario no necesita detenerse en la fase de marcado y borrado simultáneos. El hilo de usuario "Stop The World" debe detenerse durante el marcado y remarcado inicial .

La primera etapa (marcaje inicial): La etapa inicial es solo marcar los objetos que GC Roots puede asociar directamente, así que aunque el hilo del usuario se suspenderá en esta etapa, la velocidad es muy rápida.

La segunda etapa (marca de simultaneidad): esta etapa es el proceso de atravesar todo el gráfico de objetos desde los objetos directamente asociados con GC Roots. Esta etapa toma mucho tiempo y consume ciertos recursos del sistema. Sin embargo, el hilo del usuario aún se ejecutará normalmente. .

La tercera etapa (volver a marcar): dado que el marcado simultáneo se ejecuta al mismo tiempo que los hilos del usuario, este proceso generará algo de "basura" nueva y algo de "basura" ya no será "basura". Volver a marcar es para corregir el proceso concurrente generación Este proceso será un poco más largo que la etapa inicial, pero aún es relativamente corto.

La cuarta etapa (limpieza concurrente): esta etapa es para limpiar los objetos que se han marcado como "muertos". Dado que el algoritmo de limpieza de marcas no necesita mover objetos, este proceso se puede ejecutar simultáneamente con los hilos del usuario.

3.2 Desventajas obvias de CMS

CMS es un excelente GC. Sus principales ventajas se pueden ver en su nombre. Pero aún tiene obvias desventajas:

  1. CMS es muy sensible a los recursos del procesador. De hecho, los programas orientados a la concurrencia son muy sensibles a los recursos del procesador. En la etapa de concurrencia, aunque no pausará el hilo del usuario, hará que el hilo del usuario se ejecute lentamente porque ocupa el sistema Recursos. Reducir el rendimiento total. Pero para ser honesto, en el nivel de hardware moderno de hoy, no es tan importante.
  2. CMS no puede lidiar con basura flotante (Floating Garbage) , lo que lleva a un GC completo "Stop The World" completo. En la fase de limpieza simultánea, el hilo del usuario todavía se está ejecutando y generando nuevos objetos basura. Y este objeto basura no puede estar en este Eliminado por etapas. Estos objetos basura se denominan basura flotante. Estos objetos basura flotantes aparecen después de la fase de limpieza simultánea. Solo se pueden eliminar hasta el siguiente GC.
  3. El CMS tiene el riesgo de "Fallo del modo concurrente". También se debe a que los subprocesos del usuario todavía se ejecutan al mismo tiempo durante la fase de recolección de basura, por lo que debe reservar espacio para los subprocesos del usuario. Pero si es un GC paralelo, solo el GC se está ejecutando durante el GC, por lo que puede esperar hasta que el área para personas mayores esté casi llena antes de ejecutar. Pero el CMS simultáneo no puede. Entonces, ¿cuánto espacio se debe reservar para los hilos de usuario? Esto es un problema. Si el espacio reservado es no es suficiente para que se ejecuten los subprocesos del usuario, solo habrá "Fallo de modo concurrente". En este momento, la JVM tendrá que iniciar una solución alternativa: congelar los subprocesos del usuario y habilitar temporalmente Serial Old para realizar la recolección de basura en la generación anterior. causará una pausa más larga.
  4. Las deficiencias del algoritmo mark-sweep en sí. También introduje esto en el artículo correspondiente, es decir, el algoritmo mark-sweep provocará una gran cantidad de fragmentación de la memoria . Cuando la fragmentación de la memoria haya afectado la asignación de memoria del objeto, tendrá para activar un GC completo por adelantado. Para resolver este problema, la JVM puede establecer dos parámetros. El primero es: cuando se debe realizar FullGC, la memoria se desfragmenta. El segundo es: después de que se ejecuten varios GC, ser fragmentado antes de la próxima clasificación de GC

4.¡Superclave GC mixta (GC mixta)!

En la actualidad, solo hay G1 (Garbage First) disponible comercialmente Mixed GC . G1 GC es un logro histórico en la historia del desarrollo de recolectores de basura . G1 fue pionero en la idea de diseño de recolectores para recolección parcial y la forma de diseño de memoria basado en Región .

G1 fue creado para ser el reemplazo y sucesor de CMS y Parallel Old + Parallel Scavenge. El objetivo oficial establecido para G1 es obtener el mayor rendimiento posible con un retraso controlable. Conviértete en un recopilador de funciones completo. ** En JDK9 y versiones más avanzadas, G1 se ha convertido en el GC predeterminado. Ya no se recomienda CMS.

Dado que G1 es un GC innovador, naturalmente necesitamos entender su innovador y en qué se diferencia de otros GC clásicos.

4.1 Innovación de G1

1. Disposición de la memoria basada en regiones : todo el mundo sabe que la memoria dinámica en el GC anterior se basa en la teoría generacional. De hecho, G1 también se basa en la teoría generacional. Pero no asigna el espacio en la memoria dinámica de forma continua. Será La memoria del montón se divide en muchas Regiones. Cada Región puede ser la generación anterior, tal vez Edén, Superviviente en la nueva generación. Y si la memoria de un objeto excede la mitad de la Región, entonces el objeto será juzgado como un gran Objeto. Habrá un área dedicada de Humongous dedicada al almacenamiento. Si un objeto súper grande excede toda la Región, se almacenará en N áreas consecutivas de Humongous. Humongous generalmente se trata como una vejez .

La comparación entre la distribución de memoria regional y la distribución de memoria clásica es la siguiente:

Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí

2. Modelo de tiempo de pausa predecible (para recopilación parcial)

A diferencia del GC anterior, que es un GC menor o un GC mayor **, G1 no realiza GC en toda la generación joven o vieja. En cambio, el GC se realiza en la unidad de Región **. G1 hace un juicio de valor para cada Región. El índice de juicio de valor es principalmente de dos puntos: el tiempo requerido para esta colección y el tamaño del bloque de espacio obtenido por esta colección. Y se mantiene una lista de prioridades en segundo plano, y la colección se procesa primero de acuerdo con la colección permitida tiempo de pausa establecido por el usuario. Regiones con el mayor valor. Este también es el origen del nombre Garbage First. Este método de recolección parcial asegura que el recolector G1 obtenga la mayor eficiencia de recolección posible en un tiempo limitado. Pero debe explicarse : el usuario establecerá un tiempo de pausa, pero es posible que el GC no esté necesariamente dentro de este tiempo, pero tratará de hacerlo.

4.2 Proceso de ejecución G1

  1. Marcado inicial
  2. Marcado concurrente
  3. Marcado final
  4. Borrar filtro (recuento y evacuación de datos en vivo)

Entre ellos, TAMS y SATB se presentarán más adelante.

Etapa de marcado inicial : En esta etapa, GC solo marca los objetos con los que GC Roots puede asociarse directamente. Y modificar TAMS (Top at Mark Start se presentará más adelante) . Cuando la siguiente etapa de marcado concurrente, los objetos se pueden asignar correctamente en la región. Esta etapa debe detener el hilo de usuario "Stop The World". Pero el tiempo es muy corto

Fase de marcado simultáneo : esta fase analizará la accesibilidad de los objetos en el montón de GC Roots para averiguar los objetos que se van a reciclar. Lleva mucho tiempo, pero se puede ejecutar al mismo tiempo. Es similar a CMS, pero clasificará SATB (Instantánea original) objetos registrados cuyas referencias cambian durante la concurrencia

Fase de calificación final : se realiza una breve pausa en el hilo del usuario, que se utiliza para procesar una pequeña cantidad de registros SATB que aún quedan después de la fase de calificación concurrente.

Etapa de cribado y limpieza : Responsable de actualizar el valor de la Región y luego realizar una clasificación y formular un plan de tiempo de acuerdo con el tiempo de pausa esperado por el usuario. Finalmente, los objetos en la Región recolectada se copian a la Región vacía, y Se limpian los objetos de toda la Región antigua Esta etapa implica el movimiento de objetos vivos y se ejecuta en paralelo por múltiples hilos, por lo que el hilo del usuario debe estar suspendido.

Se puede ver que además de la fase de marcado concurrente, el colector G1 necesita suspender el hilo del usuario en otras fases, lo cual es determinado por G1 no solo en busca del tiempo de respuesta.

Desde un punto de vista general, G1 utiliza un algoritmo de organización de marcas, pero desde un punto de vista parcial (entre dos regiones) utiliza un algoritmo de copia de marcas, de esta forma no habrá fragmentación de la memoria .

5. Detalles del análisis de accesibilidad concurrente

Puede encontrar que la fase de marcado en los colectores CMS y G1 es concurrente, lo cual es diferente del GC anterior, entonces, ¿por qué puede ser concurrente en la fase de marcado? Los hilos de usuario también se ejecutan al mismo tiempo durante este período. La referencia La relación puede cambiar durante el período. Esto puede causar dos problemas:

  1. Resulta que el objeto que debería morir se considera vivo , lo que generará basura flotante, pero no es un problema importante y es aceptable. Está bien reciclarlo en el próximo GC.
  2. Resulta que el objeto que debería sobrevivir se considera que ha muerto . Este es un gran problema que hará que el programa se bloquee. Debemos resolverlo.

Este es el problema de consistencia . A continuación, podemos usar la marca de tres colores para demostrar el proceso de marcado. La marca de tres colores marca el objeto en tres colores según la condición "ha sido visitado":

  1. Blanco: indica que el objeto no ha sido visitado por el GC. Todos los objetos son blancos en la etapa inicial. Si todavía hay objetos que son blancos en la etapa final, entonces es inalcanzable.
  2. Gris: indica que el objeto en sí ha sido visitado, pero sus referencias a otros objetos no se han escaneado por completo.
  3. Negro: indica que el GC ha accedido al objeto y que sus referencias a otros objetos también se han escaneado por completo.

Si la marca de tres colores se usa para demostrar el proceso de escaneo, es equivalente a un proceso gradual de negro a gris y a blanco.

Inserte la descripción de la imagen aquí

Los investigadores han descubierto que el problema de la "desaparición de objetos" ocurre cuando y solo cuando se cumplen dos condiciones al mismo tiempo.

  1. El evaluador elimina todas las referencias directas o indirectas del objeto gris al objeto blanco.
  2. El evaluador ha insertado una o más referencias nuevas del objeto negro al objeto blanco.

Por lo tanto, para evitar el problema de la "desaparición del objeto", basta con destruir una de las dos condiciones, lo que lleva a dos soluciones:

  1. Instantánea al principio : G1 usa este esquema. La instantánea original destruye la primera condición: cuando el objeto gris quiere eliminar la relación de referencia con el objeto blanco, se registra la referencia que se va a eliminar. Una vez finalizada la marca de concurrencia, el gris los objetos de las referencias en estos registros se toman como raíces y se escanean nuevamente.
  2. Actualización incremental : CMS usa este esquema. La actualización incremental destruye la segunda condición: cuando un objeto negro inserta un nuevo puntero a un objeto blanco, esto se registra y se espera hasta el final de la marca concurrente Luego, escanea el objeto negro en el registro nuevamente

6 Comparación de G1 y CMS

Como una opción popular para GC del lado del servidor, G1 inevitablemente se comparará con el CMS anterior. Algunas personas piensan que es necesario comparar G1 con CMS, porque CMS ha sido oficialmente abandonado. Pero, de hecho, CMS no lo ha hecho completamente. reemplazado por G1. En algunos escenarios específicos, el rendimiento de G1 no es tan bueno como el de CMS. Las diferencias entre ellos son las siguientes:

  1. G1 puede lograr un mayor rendimiento mientras intenta cumplir con el tiempo de respuesta establecido por el usuario
  2. G1 no generará fragmentación de memoria durante la ejecución. Esto se debe en realidad a que CMS se basa en el algoritmo de eliminación de marcas, mientras que G1 se basa en el algoritmo de clasificación de marcas en su conjunto, y parcialmente en el algoritmo de copia de marcas.
  3. CMS usa un algoritmo de actualización incremental (Incremental Update) para resolver el problema de consistencia en la fase de marcado concurrente , mientras que G1 usa la instantánea original (Snapshot At The Beginning STAB) .
  4. El uso de memoria y la carga de ejecución de G1 en el proceso de ejecución son más altos que los de CMS. El uso de memoria es mayor (aproximadamente un 10% -20% más) porque cada región de G1 tiene un conjunto recordado (conjunto de memoria) y la ejecución La carga es mayor, lo más alto es que usan barreras de escritura para mantener el conjunto recordado, pero debido a que el conjunto recordado de G1 es más complejo, generará más carga.
  5. G1 utiliza los algoritmos e ideas más recientes y pioneros. Por lo tanto, todavía hay mucho margen de mejora y dividendos. Por otro lado, no se puede ignorar el soporte de Oracle para G1.

En resumen: en un entorno con poca memoria y recursos del sistema insuficientes, el efecto de usar CMS puede ser mejor. Por el contrario, G1 es una mejor opción. En términos generales, este punto crítico es (heap La memoria está entre 6-8G) .

Supongo que te gusta

Origin blog.csdn.net/qq_44823898/article/details/110007459
Recomendado
Clasificación