Se superó el límite de gastos generales de GC

93

¿Cuál es el tiempo de muestreo que utiliza JVM para generar 'java.lang.OutOfMemoryError: GC overhead limit excedido'? Sé que puede controlar el 98% y el 2% con los parámetros GCTimeLimit y GCHeapFreeLimit, pero ¿cuál es el tiempo de muestreo?

PRK
fuente

Respuestas:

82

Desde Java SE 6 HotSpot [tm] Ajuste de recolección de basura de máquina virtual

el seguimiento

Tiempo de GC excesivo y OutOfMemoryError

El recolector concurrente lanzará un OutOfMemoryError si se gasta demasiado tiempo en la recolección de basura: si más del 98% del tiempo total se dedica a la recolección de basura y se recupera menos del 2% del montón, se lanzará un OutOfMemoryError. Esta característica está diseñada para evitar que las aplicaciones se ejecuten durante un período prolongado de tiempo mientras avanzan poco o ningún progreso porque el montón es demasiado pequeño. Si es necesario, esta función se puede desactivar agregando la opción -XX: -UseGCOverheadLimit a la línea de comando.

La política es la misma que la del recopilador paralelo, excepto que el tiempo dedicado a realizar recopilaciones simultáneas no se cuenta para el límite de tiempo del 98%. En otras palabras, solo las recolecciones realizadas mientras la aplicación está detenida cuentan para el tiempo de GC excesivo. Tales colecciones se deben típicamente a un fallo de modo concurrente o una solicitud de colección explícita (por ejemplo, una llamada a System.gc ()).

junto con un pasaje más abajo

Uno de los usos más comunes de la recolección de basura explícita ocurre con la recolección de basura distribuida (DGC) de RMI. Las aplicaciones que utilizan RMI hacen referencia a objetos en otras máquinas virtuales. La basura no se puede recolectar en estas aplicaciones distribuidas sin recolectar ocasionalmente el montón local, por lo que RMI fuerza recolecciones completas periódicamente. La frecuencia de estas colecciones se puede controlar con propiedades. Por ejemplo,

java -Dsun.rmi.dgc.client.gcInterval=3600000

-Dsun.rmi.dgc.server.gcInterval=3600000 especifica la recopilación explícita una vez por hora en lugar de la tasa predeterminada de una vez por minuto. Sin embargo, esto también puede hacer que algunos objetos tarden mucho más en recuperarse. Estas propiedades se pueden establecer tan altas como Long.MAX_VALUE para hacer que el tiempo entre colecciones explícitas sea efectivamente infinito, si no se desea un límite superior en la puntualidad de la actividad de DGC.

Parece implicar que el período de evaluación para determinar el 98% es de un minuto, pero podría configurarse en la JVM de Sun con la definición correcta.

Por supuesto, son posibles otras interpretaciones.

Edwin Buck
fuente
5
La recolección de basura distribuida de RMI es una actividad no relacionada con la recolección de basura regular. Así que no veo cómo puede inferir lo que acaba de hacer.
Stephen C
2
La inferencia no es perfecta ni correcta, por eso se usa "parece implicar" en lugar de "implica". Si está de acuerdo con la observación de que si la gente de Sun utilizó un minuto para determinar el intervalo de recolección de basura para RMI, ese tiempo de recolección en la recolección concurrente solo se calcula cuando el programa principal se detiene y da un poco de fe. , entonces las probabilidades son buenas, el 98% se recopila en un minuto. Es un número mágico, pero un minuto es un número mágico que se usa a menudo en comparación con, por ejemplo, 3,5 minutos.
Edwin Buck
@StephenC ¿quiere decir que incluso si lo configuramos -XX:+DisableExplicitGC no afectará la configuración relacionada con RMI y el sistema invocará gc en la frecuencia establecida con el parámetro?-Dsun.rmi.dgc.server.gcInterval
Steephen
1
@Steephen - No. Eso no es lo que estoy diciendo. Me refiero a esta afirmación: "Parece implicar que el período de evaluación para determinar el 98% es de un minuto ..." . Y tenga en cuenta que Edwin está de acuerdo en que la inferencia es "imperfecta". La inferencia se basa en la suposición de que las personas de Sun que implementaron RMI (y DGC) estaban en estrecha comunicación con las personas que implementaron el mecanismo de límite de gastos generales de GC. Sospecho que los dos hechos ocurrieron en momentos diferentes. Tenga en cuenta que la -Dsun.rmi.dgc.server.gcIntervalpropiedad existe desde Java 1.2.
Stephen C
1
De todos modos, un mejor enfoque para encontrar la respuesta real a esta pregunta sería mirar el código fuente de OpenJDK.
Stephen C