Principios de JVM GC en la recolección de basura GCDetails
1. Parámetros de inicio
2. Principio de reciclaje
Para comprender mejor la información de GCDetails, recuerde el algoritmo de reciclaje recién nacido (imagen de Internet) Aquí no se presentará en detalle el algoritmo de reciclaje, ni se introducirán XX: MaxGCPauseMilli, XX: GCTimeRatio de ParallelGC y otros parámetros.
3. Información detallada de GC
4. Análisis
Parallel Scavenge es el algoritmo predeterminado de recolección de basura de nueva generación de JDK8, que se basa en el rendimiento. El recopilador se basa en el algoritmo de copia de marcas. La distribución de la memoria se divide en dos áreas de memoria del montón, una para la nueva generación y otra para la generación anterior. La configuración predeterminada es que la nueva generación ocupa 1/3 de la memoria del montón. La generación anterior ocupa 2/2 de la memoria del montón 3. La nueva generación se divide en Eden. Survivor_To y Survivor_From, la proporción de asignación predeterminada es 8:1:1. El área Survivor es responsable de almacenar los objetos que fallaron en la recolección de basura y promover operaciones a la generación anterior. A partir de los GCDetails anteriores, podemos analizar los principios generales de la recolección de basura.
? Tomando la primera línea como ejemplo, 131584K es el tamaño de memoria ocupado por la nueva generación antes del reciclaje, y 21503K es el tamaño de memoria ocupado por la nueva generación después del reciclaje. Se reciclan alrededor de 110 M de memoria y basura. El recolector utiliza Parallel Scavenge. 131584 K es el tamaño de memoria ocupado antes de que se recicle toda la memoria del montón. Se puede saber que 42320 K es el tamaño de memoria que ocupa este GC. este GC recicló alrededor de 89 M de memoria. El recolector de basura usa Parallel Old, lo que demora aproximadamente 8,3 milisegundos, luego la diferencia entre el tamaño de la memoria reciclada por la nueva generación y el tamaño de la memoria reciclada por todo el montón es el tamaño de la memoria de la nueva generación. actualizado a la era anterior, que se puede encontrar como 21M
? Tomando el segundo GC como ejemplo, puede ver que activó el GC completo. La versión anterior no tenía suficiente espacio. En este GC, la nueva generación recuperó 16269 K de espacio de memoria. OK, significa que la nueva generación ha recuperado toda la memoria y la generación anterior ha reciclado 316390 K-236940 K de espacio de memoria, aproximadamente 80 M. 333077K-271355K espacio de memoria, aproximadamente 61M. Se puede ver que la nueva generación ha aumentado el espacio de memoria 80-61, aproximadamente 19M.
? En experiencias de producción anteriores, siempre que la JVM o el programa no tuvieran alarmas relevantes, los parámetros de inicio rara vez se ajustaban. Al estudiar y analizar los registros de GC, encontramos que el tamaño de la memoria del montón y el tamaño de la memoria del montón. rendimiento del sistema La cantidad todavía está directamente relacionada. Puede intentar probar el rendimiento del sistema utilizando diferentes parámetros -Xms y -Xmx1. Encontraremos que si la memoria es demasiado pequeña, aparecerá young con frecuencia. Si la memoria es demasiado pequeña, aparecerá Young GC con frecuencia, e incluso GC completo o pérdidas de memoria ocurrirán con frecuencia. De hecho, el rendimiento también se verá afectado por la memoria ridículamente grande, y en el GC completo antiguo. , el tiempo STW (detener la palabra) será mayor, por lo que los parámetros de inicio adecuados son una parte esencial de las pruebas de rendimiento.
5. Parámetros de selección del recolector de basura
Dado que la nueva generación es un recolector de basura paralela, originalmente quería usar diferentes algoritmos de la era anterior para probar el rendimiento y prepararme. : UseParallelGC, XX: UseParallelOldGC, pero descubrí que el algoritmo de reciclaje en la era anterior siempre ha sido ParOldGen. Después de estar confundido por un tiempo, busqué información y descubrí que en 7 y JDK8 después de JDK 7u4, el algoritmo de nueva generación es Parallel. Scavenge y lo antiguo La era predeterminada es Parallel Old.
6. En el registro de GC anterior, hay dos corchetes, como (153088K) y (502784K) en la primera línea, que representan respectivamente el tamaño de la memoria asignada por la nueva generación y el tamaño de la memoria del montón. asignado, pero encontramos que este tamaño no es fijo. El tamaño entre paréntesis cambia en la séptima generación o incluso después del GC. Es por eso que, de hecho, Parallel Scavenge de JDK8 tiene el parámetro -XX: UseAdaptiveSizePolicy habilitado de forma predeterminada. La cantidad y el tiempo de recolección de basura se ajustan de acuerdo con el rendimiento para ajustar dinámicamente el tamaño del área de memoria. Aunque la nueva generación tiene una relación de asignación predeterminada SurvivorRatio = 8, no será un tamaño fijo. 8 en los parámetros de inicio, la memoria asignada no se ajustará dinámicamente, por lo que puedes experimentar con ella.
? En la nueva generación de recolección de basura anterior a JD8, además de Parallel Scavenge, tanto Serial como ParNew se pueden probar mediante las siguientes instrucciones. Todos se basan en el algoritmo de copia de marcas. en la nueva generación también se utiliza el mismo método de análisis.
1. Parámetros de inicio
2. Como período de recolección de basura de la generación anterior, CMS tiene como objetivo reducir el tiempo de inactividad de la recolección de basura. Utiliza un algoritmo de eliminación de marcas y solo puede ser. Utilizado con la recolección de basura de nueva generación del mismo ParNew y Serial, JDK9 solo admite el uso de la misma parte que ParNew. El principio no se explicará en detalle, principalmente analizando el registro de GCDetails para profundizar la comprensión de esta parte. Hay dos conceptos más importantes, uno es el método de notación de tres colores y la dislexia. El otro es la estructura de la tabla de tarjetas. Si no lo comprende, puede consultar este artículo. Creo que la escritura es más fácil. .
3. Registro de GCDetails
4. GC (Allocation Failure) utiliza ParNew como una nueva generación de algoritmo de recolección de basura. La situación de la memoria de esta parte es similar a la Parallel analizada anteriormente. Entonces esta parte analiza principalmente el principio de recolección de basura de CMS en la era anterior. Los registros de recolección de basura de CMS en realidad están estrechamente relacionados con las etapas de recolección de basura. El objetivo principal es observar los registros para fortalecer a la inversa el proceso y los principios de la recolección de basura. Los registros de recolección de basura de CMS en realidad están estrechamente relacionados con las etapas de recolección de basura. El objetivo principal es observar los registros para fortalecer inversamente el proceso y los principios de recolección de basura.
1) Marcado Inicial - CMS Marcado Inicial
? CMS Para reducir el tiempo de pausa, podemos recordar que ambas fases de marcado son STW, y el resto de fases son paralelas, en el registro El tiempo es 0. Se puede obtener cierta información a través de la línea 328. El tamaño de memoria de la versión anterior utilizada en la fase de marcado inicial es 203782K, el tamaño de memoria asignado por toda la versión anterior es 349568K, el tamaño de memoria utilizado por La memoria del montón completa es 221541 K, y la asignación de memoria del montón completa El tamaño de la memoria es 506816 K, y el tiempo de marcado también es muy corto. Desde aquí, también podemos calcular aproximadamente que el tamaño de la memoria asignada por la nueva generación es de aproximadamente 506816 K-349568 K =. 157M, que es consistente con el tamaño de la asignación de memoria de nueva generación en la primera línea.
2) Marca concurrente-CMS-concurrent-mark. La marca concurrente marca principalmente la accesibilidad del objeto en función de la marca inicial. Se sabe que el tiempo en el registro es de 0,01 s. ;Prelimpieza-CMS-concurrent-preclean, la prelimpieza resuelve principalmente el problema de la prelimpieza empresarial-CMS-concurrent-preclean en el proceso de marcado concurrente. La prelimpieza resuelve principalmente la modificación de las relaciones de referencia de objetos mediante subprocesos. proceso de marcado concurrente (incluidas referencias entre generaciones y modificación de referencias), principalmente escaneando la tabla de tarjetas marcada como "bloque sucio", que tarda 0,01 s
3) Prelimpieza terminable-CMS-concurrent-abortable-preclean; , es posible que este paso no se ejecute. Este paso no se ejecuta necesariamente. Si la memoria de la nueva generación es menor que CMSScheduleRemarkEdenSizeThreshold, no se ejecutará. Si es mayor que el valor de la marca de continuación (repetida continuamente), aparecerán condiciones de salida, como el número. de bucles, umbral de tiempo, utilización de la memoria del área del Edén, etc. Antes de que salga el bucle, se realizará un YGC para reducir la presión sobre la calificación final más adelante (debido a la existencia de punteros para la generación joven en la generación anterior, Se puede ver en el registro que se realizaron tres YGC en la fase de limpieza previa abortable de 0.331. A juzgar por la situación de la memoria, una gran cantidad de objetos se promueven de la generación más nueva a la generación anterior.
Pequeña pregunta : En esta parte, observamos que el indicador de tiempo es 0,003/0,136 segundos, y 0,003 segundos es el tiempo total de ejecución de la CPU, 0,136 segundos. Hay una diferencia entre los dos. De hecho, no tengo una respuesta clara para esta parte. Mi primera sensación es que puede estar esperando una nueva generación de GC. p>
3) Calificación final: comentarios finales de CMS
<. p> El resultado de la calificación final se puede analizar desde el tiempo de registro 0.468. El tamaño de 17759K es la memoria utilizada por la nueva generación (en paralelo) es el tiempo SWT de la marca final, el procesamiento de referencias débiles es el tiempo para limpiar. referencias débiles, la descarga de clases es el momento de descargar las clases no utilizadas, borrar la tabla de símbolos es limpiar la tabla de símbolos, según tengo entendido, es limpiar las referencias de símbolos, borrar la tabla de cadenas es limpiar la tabla de caracteres, según tengo entendido, es una limpieza literal La marca final de uso de memoria del CMS después del envejecimiento es 334051 K y el uso de memoria de montón es 351810 K.4) Limpieza concurrente-CMS-barrido-concurrente, que es fácil de entender como limpieza concurrente; reinicio concurrente-CMS-reinicio-concurrente, reajusta la estructura de memoria de CMS para la siguiente recolección de basura.
5. Ajuste
? En CMS, la recolección de basura concurrente no necesariamente tiene éxito, puede fallar, lo que cambiará al antiguo algoritmo de recolección de basura en serie para evitar esto. En este caso, puede considerar utilizar el parámetro CMSInitiatingOccupancyFraction, el valor predeterminado es 92?