Se utiliza java version "1.8.0_161"
para realizar pruebas.
Configure los parámetros de inicio de la JVM como:
-Xms10m -Xmx10m -XX:+PrintGCDetails -Xloggc:/data/log/gc.log
-XX:+PrintGCDateStamps -XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/data/log
Ejecute el fragmento de código:
public class RuntimeConstantPoolOOM {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
int i = 0;
while (true) {
list.add(String.valueOf(i++).intern());
}
}
}
Entonces lanza una excepción
Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
Veamos el gc.log generado.
CommandLine flags:
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/data/log
-XX:InitialHeapSize=10485760
-XX:MaxHeapSize=10485760
-XX:+PrintGC
-XX:+PrintGCDateStamps
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-XX:+UseCompressedClassPointers
-XX:+UseCompressedOops
-XX:+UseParallelGC
Este es el parámetro de la máquina virtual que se ejecuta en gc.log, sabemos que nuestro recolector de basura es ParallelGC.
GC menor
GC Menor: GC Cenozoico se refiere a eventos GC que ocurren en el Cenozoico. La mayoría de los objetos Java en el Cenozoico nacen y mueren. Los GC menores son frecuentes y la velocidad de recolección es muy rápida.
2018-11-18T19:31:12.804-0800: 0.207:
[ GC (Allocation Failure) [PSYoungGen: 2048K->496K(2560K)]
2048K->588K(9728K), 0.0011270 secs ]
[Times: user=0.00 sys=0.01, real=0.00 secs]
2018-11-18T19:31:12.804-0800
: El momento de inicio del evento de GC0.207
: La hora de inicio del evento de GC, en relación con la hora de inicio de la JVM, en segundosGC
: Un signo que se utiliza para distinguir si es GC menor o GC completo, donde indica la aparición de GC menorAllocation Failure
: La causa de la recolección de basura, este GC se debe a que la estructura de datos recién asignada no se puede almacenar en la generación jovenPSYoungGen
: Representa la nueva generación, este nombre lo determina el recopilador de GC, el recopilador aquí es Parallel Scavenge, el recopilador de nueva generación utiliza un algoritmo de replicación para la recopilación2048K->496K(2560K)
: Indica el uso de la memoria de la generación joven antes y después de este CG. 2560k entre paréntesis representa el tamaño total de la generación joven. La generación joven se subdivide en los espacios Eden, From Survivor y To Survivor.2048K->588K(9728K)
: Indica el uso de la memoria de pila antes y después de este GC, el tamaño de la memoria entre paréntesis indica la memoria de pila disponible0.0011270 secs
: La duración del evento GC, en segundosTimes: user=0.00 sys=0.01, real=0.00 secs
: La duración del evento GC se mide mediante una variedad de categorías:
user
-Esta recolección de basura, todo el tiempo de CPU consumido por el subproceso de recolección de basura, es decir, el tiempo de CPU consumido por el modo de usuario -el tiempo de CPU
sys
consumido por el modo de kernel
real
-el tiempo de pausa de la aplicación (Hora del reloj), incluidos varios tiempos de espera no operativos, como la espera de E / S de disco, bloqueo de subprocesos, el tiempo de CPU no incluye estos
Tamaño del montón =
generación joven (eden + de + a) + generación anterior, la generación joven recuperó 1552 k de 2048 K-> 496 K, y la
memoria del montón recuperó 1460 k de 2048 K-> 588 K. Se
puede ver que hay 1552-1460 = 92 k objetos de La generación joven actualizada a la generación anterior
GC completo
El GC (o GC mayor) que se produjo en la vejez suele ir acompañado de al menos un GC menor. La velocidad del GC completo es generalmente más de 10 veces más lenta que la del GC menor.
2018-11-18T19:31:12.857-0800: 0.259:
[Full GC (Ergonomics) [PSYoungGen: 480K->0K(2560K)]
[ParOldGen: 5706K->5764K(7168K)] 6186K->5764K(9728K),
[Metaspace: 3317K->3317K(1056768K)], 0.0556835 secs]
[Times: user=0.09 sys=0.00, real=0.06 secs]
[Full GC (Ergonomics) [PSYoungGen: 480K->0K(2560K)]
: El GC de generación anterior, también conocido como GC mayor, irá acompañado de un GC de generación joven (GC menor), que es más lento[ParOldGen: 5706K->5764K(7168K)] 6186K->5764K(9728K)
: GC de generación anterior, la versión de generación anterior de Parallel Scavenge,5706K->5764K(7168K)]
esto es similar al GC de generación joven, lo que indica el espacio ocupado antes y después de GC.6186K->5764K(9728K)
Indica el uso de la memoria del montón antes y después de GC, el tamaño de la memoria del montón entre paréntesis[Metaspace: 3317K->3317K(1056768K)]
: Representa el uso de memoria del metaespacio antes y después de GC. Los paréntesis indican el tamaño total del metaespacio de JVM .
Referencia: Comprensión de los registros de recolección de basura
JVM (13) Comprensión de los registros de GC " Comprensión
en profundidad de la máquina virtual Java" (6) Análisis de uso de memoria de pila , Interpretación del registro de GC del recolector de basura