old memories gen eden java memory-management garbage-collection jvm objectsize

java - memories - Tamaño de los objetos enormes asignados directamente a la antigua generación



ps eden space (3)

El tamaño máximo de un objeto que HotSpot JVM puede asignar en la generación joven es casi tan grande como el tamaño de Eden (YoungGen menos dos espacios de Sobrevivientes).

Así es como se ve la asignación rougly:

  1. Use el buffer de asignación local de subprocesos (TLAB), si tlab_top + size <= tlab_end
    Este es el camino más rápido. La asignación es solo el incremento del puntero tlab_top .
  2. Si TLAB está casi lleno, cree un nuevo TLAB en Eden y vuelva a intentarlo en un TLAB nuevo.
  3. Si el espacio restante de TLAB no es suficiente pero aún es demasiado grande para descartarlo, intente asignar un objeto directamente en Eden. La asignación en Eden también es un incremento de puntero ( eden_top + size <= eden_end ) utilizando una operación atómica, ya que Eden se comparte entre todos los subprocesos.
  4. Si la asignación en Eden falla, normalmente ocurre una colección menor.
  5. Si no hay suficiente espacio en Eden, incluso después de Young GC, se realiza un intento de asignación directa en la generación anterior.

Recientemente he estado leyendo sobre asignaciones de objetos en diferentes generaciones en Java. La mayoría de las veces, los objetos nuevos se asignan en Eden (parte de Young Generation) y luego se promocionan a Old Generation si se cumple alguno de los siguientes criterios.

(1) La edad del objeto alcanzó el umbral de tenencia.
(2) El espacio de supervivencia (to) está lleno cuando los objetos se copian de Eden (o) de otro espacio de supervivencia (de)

Pero también hay un caso especial en el que los objetos se asignan directamente en la vieja generación en lugar de ser promovidos de la generación joven. Esto sucede cuando el objeto que intentamos crear es enorme (posiblemente del orden de unos pocos MB).

¿Hay alguna forma de saber el tamaño / límite de los objetos enormes / gigantescos? Soy consciente de los enormes criterios de los objetos para el recolector de basura G1. Solo quiero saber el límite de tamaño antes o en Java 6 .

Gracias por tu tiempo :)


Puedes establecer el límite usando la siguiente bandera

XX:PretenureSizeThreshold=size

su valor predeterminado es 0 Supongo que, de forma predeterminada, si no lo configura, no se considera con el valor = 0 , eso significa que, de forma predeterminada, no hay un valor máximo que actúe como umbral, por lo que el objeto predeterminado se promueve solo en función de número de supervivencia GC

Versión HotSpot

java version "1.7.0_45" Java(TM) SE Runtime Environment (build 1.7.0_45-b18) Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)

para obtener todas las opciones de vm (soportadas) puedes ejecutar

java -XX:+PrintVMOptions -XX:+AggressiveOpts -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+PrintFlagsFinal -version

y luego puede consultar el documento de la opción de hotspot vm o la opción particular de google si no está en la lista

byte[] array = new byte[300*1024*1024]; for(MemoryPoolMXBean memoryPoolMXBean: ManagementFactory.getMemoryPoolMXBeans()){ System.out.println(memoryPoolMXBean.getName()); System.out.println(memoryPoolMXBean.getUsage().getUsed()); }

salidas:

$ java -Xmx1500m -Xms1500m -Xmn500m -XX:PretenureSizeThreshold=100000000 -XX:+PrintGCDetails JVMMemoryInspection Code Cache 393664 PS Eden Space 330301752 PS Survivor Space 0 PS Old Gen 0 PS Perm Gen 2749520


Banderas JVM:

-Xms1G -Xmx1G -Xmn500m -XX: PretenureSizeThreshold = 100000000 -XX: + PrintGCDetails

Al fijar el tamaño de la generación joven a 500 MB, eden llega a los 384 MB, por lo que cualquier objeto mayor que 384 MB va directamente a OldGen y el objeto a menos de 384 MB se asigna en el mismo Eden. Puedes encontrar los usos de la generación a continuación.

byte [] array = nuevo byte [400 * 1024 * 1024];

PSYoungGen total 448000K, used 30720K eden space 384000K, 8% used from space 64000K, 0% used to space 64000K, 0% used ParOldGen total 536576K, used 409600K object space 536576K, 76% used

byte [] array = nuevo byte [300 * 1024 * 1024];

PSYoungGen total 448000K, used 337920K eden space 384000K, 88% used from space 64000K, 0% used to space 64000K, 0% used ParOldGen total 536576K, used 0K object space 536576K, **0% used**

Para una asignación de 400 MB, el uso de eden es del 8% mientras que el uso de la generación anterior es del 76% Para la asignación de 300 MB, el uso de eden es del 88% mientras que el uso de la generación anterior es del 0% Por lo tanto, es claro que todos los objetos cuyo tamaño sea mayor que el eden serán asignado directamente en la antigua gen.

Gracias, apangin y Jigar por tus valiosas ideas :)
Creo que -XX: PretenureSizeThreshold no se considera en absoluto.