CMS-Recolector de barrido de marcas concurrente
El recopilador de barrido de marcas concurrente (CMS) está diseñado para aplicaciones que prefieren tiempos de pausa cortos en la recolección de basura y se puede utilizar mientras la aplicación se está ejecutando. recursos con el recolector de basura. En general, las aplicaciones que tienen conjuntos de datos a largo plazo relativamente grandes (generación a largo plazo) y se ejecutan en computadoras con dos o más procesadores a menudo se beneficiarán del uso de este recopilador. Sin embargo, cualquier aplicación que no requiera largos tiempos de pausa debería considerar el uso de este recopilador. El recopilador de CMS se habilita mediante la opción de línea de comando -XX:+useconcmasweepgc.
Al igual que otros recopiladores disponibles, los recopiladores CMS se transmiten de generación en generación, por lo que se producen tanto la recopilación de la generación joven como la de la generación anterior; El recolector de CMS intenta realizar un seguimiento de los objetos accesibles mediante el uso de un subproceso recolector de basura independiente que se ejecuta simultáneamente con el subproceso de la aplicación, reduciendo así el tiempo de pausa causado por la colección principal. Durante cada ciclo de recopilación importante, el recopilador de CMS pausa brevemente todos los subprocesos de la aplicación al comienzo de la recopilación y nuevamente durante el proceso de recopilación. La segunda pausa suele ser la más larga de las dos. Durante las dos pausas, se utilizaron varios hilos para la recopilación. El resto del trabajo de recolección, incluido el seguimiento de la mayoría de los objetos activos y la limpieza de objetos inalcanzables, lo realizan uno o más subprocesos del recolector de basura que se ejecutan simultáneamente con la aplicación. Las recolecciones de la generación más joven se pueden intercalar con las recolecciones de la generación anterior en curso y se realizan de manera similar a un recolector de basura paralelo (específicamente, los subprocesos de la aplicación se detienen durante las recolecciones de la generación más joven).
Error en el modo concurrente.
El recolector de CMS utiliza uno o más subprocesos del recolector de basura que se ejecutan simultáneamente con los subprocesos de la aplicación, con el objetivo de completar la recolección antes de que expire la fecha límite. Como se mencionó anteriormente, durante el funcionamiento normal, el recopilador de CMS realiza la mayor parte de su trabajo de seguimiento y limpieza mientras el subproceso de la aplicación aún se está ejecutando, por lo que el subproceso de la aplicación solo ve pausas breves. Sin embargo, si el recopilador de CMS no puede completar la recopilación de objetos inalcanzables antes de que se llene la generación anterior, o si las asignaciones no pueden satisfacerse con bloques de espacio libre en la generación anterior, la aplicación se detendrá y completará la recopilación, y todos los subprocesos de la aplicación se detendrán. . No completar la recopilación al mismo tiempo se denomina falla del modo concurrente, lo que indica que es necesario ajustar los parámetros del recopilador de CMS. Se informará una interrupción del modo concurrente si una recolección concurrente es interrumpida por una recolección de basura explícita (System.gc()) o por una recolección de basura requerida para proporcionar información a las herramientas de diagnóstico.
GC tarda demasiado y se producen errores de falta de memoria.
Si el tiempo de recolección de basura es demasiado largo, el recolector de CMS generará un OutOfMemoryError: si el tiempo de recolección de basura excede el 98% del tiempo total y el montón recuperado es inferior al 2%, entonces se generará un OutOfMemoryError. ser arrojado. Esta función sirve para evitar que la aplicación se ejecute durante mucho tiempo y progrese poco porque el montón es demasiado pequeño. Si lo desea, puede desactivar esta función agregando la opción -XX:-UseGCOverheadLimit a la línea de comando.
Esta estrategia es la misma que en el recopilador paralelo, excepto que el tiempo para realizar recopilaciones simultáneas no está incluido en el límite de tiempo del 98%. En otras palabras, solo las recopilaciones realizadas mientras la aplicación está detenida se contabilizarán como tiempo de GC excesivo. Esta recopilación suele deberse a un fallo del modo concurrente o a una solicitud de recopilación explícita (por ejemplo, una llamada a System.gc).
Basura flotante
Como todos los demás recolectores en Java HotSpot VM, el recolector CMS es un recolector de seguimiento que al menos identifica todos los objetos accesibles en el montón. En palabras de Richard Jones y Raphael D. Lins en su publicación Garbage Collection. Según Richard Jones y Raphael D. Lins en su publicación Garbage Collection: Automatic Dynamic Memory Algorithms, es un recolector de actualizaciones incrementales. Debido a que el subproceso de la aplicación y el subproceso del recolector de basura se ejecutan simultáneamente durante el proceso de recolección principal, los objetos rastreados por el subproceso del recolector de basura pueden volverse inaccesibles al final del proceso de recolección. Estos objetos inaccesibles que no se reciclan se denominan basura flotante. La cantidad de basura flotante depende de la duración del ciclo de recolección concurrente y de la frecuencia de las actualizaciones de referencia de la aplicación, también conocidas como mutaciones.
Además, dado que las generaciones más jóvenes y mayores se recopilan de forma independiente, cada una es una fuente esencial para la otra. Como pauta aproximada, intente aumentar el tamaño de la generación anterior en un 20% para tener en cuenta la basura flotante. Al final de un ciclo de recolección concurrente, la basura flotante en el montón se recolecta en el siguiente ciclo de recolección.
Abortar
El recopilador de CMS pausará la aplicación dos veces durante un ciclo de recopilación simultáneo. La primera pausa es para marcar objetos que provienen directamente de la raíz (por ejemplo, referencias de objetos de registros y pilas de subprocesos de aplicaciones, objetos estáticos, etc.). ) está vivo como objetos en otras partes del montón (como los jóvenes). La primera pausa se llama pausa inicial de marcado. La segunda pausa ocurre al final de la fase de rastreo concurrente. Puede encontrar objetos omitidos por el seguimiento concurrente que el subproceso de la aplicación omitió después de que el recopilador de CMS haya terminado de rastrear un objeto. Esta segunda pausa se llama pausa de comentario.
Fase de concurrencia
El seguimiento de concurrencia del gráfico de objetos accesibles se produce entre la pausa de marcado inicial y la pausa de remarcado. Durante esta fase de seguimiento simultáneo, uno o más subprocesos recolectores de basura simultáneos pueden estar utilizando recursos del procesador que podrían estar disponibles para la aplicación. Por lo tanto, durante esta y otras fases de concurrencia, las aplicaciones informáticas pueden experimentar una disminución correspondiente en el rendimiento de la aplicación incluso si los subprocesos de la aplicación no están suspendidos. Después de una pausa de comentarios, una fase de limpieza paralela recopila objetos que se confirma que son inaccesibles. Una vez que se completa un ciclo de recopilación, el recopilador de CMS espera hasta que comience el siguiente ciclo de recopilación importante, lo que consume muy pocos recursos informáticos.
Inicie un ciclo de recolección concurrente
En el recolector en serie, la recolección de basura se producirá siempre que la generación joven esté llena. Cuando se complete la recolección, todos los subprocesos de la aplicación se detendrán. Por el contrario, el inicio de una recopilación concurrente debe garantizar que la recopilación pueda completarse antes del final del período de antigüedad; de lo contrario, la aplicación observará pausas prolongadas debido a fallas en el modo concurrente; Hay varias formas de iniciar colecciones simultáneas.
Basándose en la historia reciente, el recopilador de CMS estima el tiempo que queda antes de que se agote la "vieja generación" y el tiempo necesario para los ciclos de recopilación simultáneos. Utilizando estas estimaciones dinámicas, se inician ciclos de recolección simultáneos para completar el ciclo de recolección antes de que se agote la generación anterior. Estas estimaciones están ponderadas para ser seguras, ya que las fallas en modo concurrente pueden ser muy costosas.
Si la tasa de ocupación de la generación anterior excede la tasa de ocupación inicial (porcentaje de la generación anterior), también se iniciará la recolección simultánea. El valor predeterminado para este umbral de ocupación inicial es aproximadamente del 92 %, pero este valor cambiará de una versión a otra. Este valor se puede establecer mediante la opción de línea de comando -xx:cmsinititingaccouncyfraction=
Pausas programadas
Las pausas para las colecciones de la generación joven y las pausas para las colecciones de la generación anterior ocurren de forma independiente. No se superponen, pero pueden ocurrir en rápida sucesión, por lo que una pausa para una serie, seguida de una pausa para otra serie, aparecerá como una única pausa larga. Para evitar esto, el recopilador de CMS intentará programar una pausa comentada entre la pausa de la generación anterior y la pausa de la siguiente generación, aproximadamente en el medio. Actualmente, no existe tal disposición para la pausa de marca inicial, que suele ser mucho más corta que la pausa de observación.
Modo incremental
Tenga en cuenta que el modo incremental ha quedado obsoleto en Java SE 8 y es posible que se elimine en una versión principal futura.
El recopilador CMS se puede utilizar en un patrón que complete incrementalmente la fase concurrente. Recuerde que durante la fase concurrente, el subproceso del recolector de basura utiliza uno o más procesadores. El propósito del modo incremental es reducir el impacto de las fases de concurrencia largas deteniendo periódicamente la fase de concurrencia y devolviendo el procesador a la aplicación. Este patrón, llamado aquí i-CMS, divide el trabajo concurrente del coleccionista en pequeños períodos de tiempo y los programa entre las generaciones más jóvenes. Esta función es útil cuando las aplicaciones que requieren tiempos de pausa cortos proporcionados por el recopilador CMS se ejecutan en una máquina con una pequeña cantidad de procesadores (por ejemplo, 1 o 2).
Un ciclo de cobranza concurrente generalmente incluye los siguientes pasos.
1- Detener todos los subprocesos de la aplicación, determinar el conjunto de objetos accesibles desde la raíz y luego reanudar todos los subprocesos de la aplicación.
2-Cuando se ejecuta un subproceso de aplicación, se utilizan uno o más procesadores para rastrear simultáneamente el gráfico de objetos accesibles.
3- Usando el procesador, rastrea las partes del gráfico de objetos que han sido modificadas desde el paso anterior.
4- Detenga todos los subprocesos de la aplicación, rastree las raíces y partes del gráfico de objetos que puedan haber sido modificadas desde la última verificación y reanude todos los subprocesos de la aplicación.
5-Utilice también un procesador para barrer los objetos inalcanzables a la lista libre para su asignación.
6-También ajuste el tamaño del montón, prepare las estructuras de datos de soporte para el siguiente ciclo de recopilación y utilice el procesador.
En términos generales, el recopilador de CMS utiliza uno o más procesadores durante la fase de marcado concurrente y no abandonará activamente estos procesadores. De manera similar, si se utilizan uno o más procesadores durante la fase de limpieza simultánea, no se abandonará. Esta sobrecarga puede causar demasiada interferencia en aplicaciones con tiempos de respuesta limitados que, de otro modo, podrían utilizar núcleos de procesamiento, especialmente en sistemas con solo uno o dos procesadores. El patrón incremental resuelve este problema al dividir las fases concurrentes en actividades de corto plazo, programadas en medio de pequeñas pausas.
El modo I-cms utiliza un ciclo de trabajo para controlar cuánta carga de trabajo puede ejecutar el recopilador CMS antes de abandonar voluntariamente el procesador. El ciclo de trabajo es el porcentaje de tiempo que se permite que el recolector CMS funcione entre generaciones jóvenes. El modo I-cms puede calcular automáticamente el ciclo de trabajo en función del comportamiento de la aplicación (el método recomendado, llamado ritmo automático), o establecer el ciclo de trabajo en un valor fijo en la línea de comando.
* *Opciones de línea de comando* *
Opciones de línea de comando que controlan el modo i-cms. Opciones recomendadas
Opciones recomendadas
Para usar i-cms con Java SE 8, use las siguientes opciones de línea de comando.
-XX:+useconcmasweepgc-XX:+CMS incrementalmode
-XX:+printgc detalles-XX:+printgc timestamps
Las dos primeras opciones están habilitadas respectivamente colector CMS e i-cms. Las dos últimas opciones no son necesarias, simplemente escriben información de diagnóstico sobre la recolección de basura en la salida estándar para que el comportamiento de la recolección de basura se pueda ver y analizar más adelante.
Para Java SE 5 y versiones anteriores, Oracle recomienda las siguientes opciones como conjunto inicial de opciones de línea de comando para i-cms.
-XX:+useconcmasweepgc-XX:+modo incremental de CMS
-xx:+detalles de printgc-xx:+marcas de tiempo de printgc.
-XX:+CMS incrementalpacing-XX:CMS incrementaldutycyclemin = 0
-XX:CMS incrementaldutycycle = 10
Aunque los tres parámetros que controlan el i- cms velocidad automática El valor de esta opción se ha convertido en el valor predeterminado en JavaSE6, pero se recomienda utilizar el mismo valor para JavaSE8.
Solución de problemas básicos
La función de ritmo automático de i-cms utiliza estadísticas recopiladas mientras el programa se está ejecutando para calcular el ciclo de trabajo para completar la recopilación simultánea antes de que se llene el montón. Sin embargo, el comportamiento pasado no predice perfectamente el comportamiento futuro y es posible que los resultados estimados no siempre sean lo suficientemente precisos como para evitar que el montón se llene. Si hay demasiados paquetes de dispositivos completamente cargados, pruebe los pasos de la tabla "Solución de problemas de la función de ritmo automático de i-CMS" a continuación, uno a la vez.
Solución de problemas de la función de conteo automático de pasos de i-cms
Resultados de la medición
La siguiente figura muestra la salida del recopilador CMS con las opciones -verbose:gc y - XX:+PrintGCDetails, se han eliminado algunos otros detalles. Tenga en cuenta que la salida del recopilador CMS se entrelaza con la salida de otros recopiladores; a menudo, se producirán muchas adquisiciones secundarias dentro de un ciclo de adquisición sincronizado.
La marca inicial de CMS indica el comienzo del ciclo de recopilación concurrente.
CMS-concurrent-mark indica el final de la fase de marcado concurrente.
CMS-concurrent-sweep indica el final de la fase de limpieza en paralelo.
Lo que no se ha discutido antes es la etapa de limpieza previa representada por CMS-concurrent-preclean. La limpieza previa es un trabajo que se puede realizar mientras se preparan las notas de CMS durante la fase de reetiquetado. La última etapa, representada por CMS-concurrent-reset, es prepararse para la próxima recopilación simultánea.
El tiempo de pausa de marcado inicial suele ser corto en comparación con el tiempo de pausa de toda la generación joven. Las fases concurrentes (marcado simultáneo, prelimpieza simultánea, limpieza simultánea) suelen tener tiempos de pausa mucho más largos que los de la generación más joven, como se muestra en la figura anterior. Sin embargo, tenga en cuenta que la aplicación no se detiene durante estas fases simultáneas. La duración de la pausa comentada suele ser equivalente a la duración aprendida por la generación más joven. Las pausas reetiquetadas se ven afectadas por algunas características de la aplicación (por ejemplo, las altas tasas de modificación de objetos aumentarán las pausas) y el tiempo desde la última colección de la generación joven (por ejemplo, más objetos en la generación joven aumentarán las pausas).