Wielkość ogromnych obiektów bezpośrednio przypisanych staremu pokoleniu

Ostatnio czytałem o alokacji obiektów w różnych generacjach w Javie. W większości przypadków nowe obiekty są przydzielane w Edenie (część młodego pokolenia), a następnie są promowane do starego pokolenia, jeśli spełnione są którekolwiek z poniższych kryteriów.

(1) Wiek obiektu osiągnął próg tenuring
(2) Survivor space (to) jest pełna, gdy obiekty są kopiowane z Edenu(lub) innej survivor space (from)

Ale jest też szczególny przypadek, w którym przedmioty są bezpośrednio przydzielane staremu pokoleniu, a nie promowane od młodego pokolenia. Dzieje się tak, gdy obiekt, który staramy się stworzyć jest ogromny (prawdopodobnie rzędu kilku MBs).


Czy Jest jakiś sposób, aby poznać rozmiar / limit ogromnych / ogromnych obiektów? Jestem świadomy wielu kryteriów obiektów dla G1 Garbage Collector. Chcę tylko znać limit rozmiaru przed lub w Javie 6 .

Dzięki za poświęcony czas:)

Author: Jigar Joshi, 2014-07-07

3 answers

Maksymalny rozmiar obiektu, który JVM może rozdysponować w młodym pokoleniu, jest prawie tak duży jak rozmiar Edenu (YoungGen minus dwie przestrzenie ocalałe).

Tak wygląda przydział:

  1. użyj lokalnego bufora alokacji wątku (tlab), jeśli tlab_top + size tlab_end
    To najszybsza droga. Alokacja jest tylko przyrostem wskaźnika tlab_top.
  2. Jeśli TLAB jest prawie pełny, utwórz nowy TLAB w Edenie i spróbuj ponownie w nowym TLAB.
  3. If TLAB pozostała przestrzeń nie wystarczy, ale nadal jest duża do odrzucenia, spróbuj przydzielić obiekt bezpośrednio w Edenie. Przydział w Edenie jest również przyrostem wskaźnika(eden_top + size eden_end) korzystanie z operacji atomowych, ponieważ Eden jest dzielony między wszystkie wątki.
  4. jeśli alokacja w Edenie nie powiedzie się, zwykle występuje zbiór mniejszy.
  5. Jeśli nie ma wystarczająco dużo miejsca w Edenie nawet po młodym GC, próba alokacji bezpośrednio w Starym pokoleniu jest podejmowana.
 21
Author: apangin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-07 21:29:43

Możesz ustawić limit używając poniższej flagi

XX:PretenureSizeThreshold=size

Jego domyślną wartością jest 0 zakładam, że domyślnie jeśli go nie ustawisz, nie będzie brany pod uwagę wartość = 0, co oznacza, że domyślnie nie ma maksymalnej wartości, która działa jako próg, domyślnie obiekt jest promowany tylko na podstawie liczby GC przetrwania

Wersja 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)

Aby uzyskać wszystkie opcje vm (obsługiwane) można uruchomić

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

A następnie możesz odwołać się do opcji hotspot vm dokument lub konkretna opcja google, jeśli nie jest wymieniona


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

for(MemoryPoolMXBean memoryPoolMXBean: ManagementFactory.getMemoryPoolMXBeans()){
    System.out.println(memoryPoolMXBean.getName());
    System.out.println(memoryPoolMXBean.getUsage().getUsed());
}

Wyjścia:

$ 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
 6
Author: Jigar Joshi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-07 22:49:47

Flagi JVM:

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

Eden ma około 384MB, więc każdy obiekt większy niż 384MB trafia bezpośrednio do Oldgena, a obiekt mniejszy niż 384MB jest przydzielany do samego Edenu. Możesz znaleźć użycie generacji poniżej

Byte [] array = new 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 = new bajt[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** 

Dla alokacji 400MB, wykorzystanie eden wynosi 8%, gdzie jako stare użycie gen wynosi 76% Dla alokacji 300Mb, wykorzystanie eden wynosi 88%, gdzie jako stare użycie gen wynosi 0% Więc jest jasne, że wszystkie obiekty, których rozmiar jest większy niż eden, zostaną przydzielone bezpośrednio do starego gen.

Dzięki apangin & Jigar za cenne spostrzeżenia:)
Myślę ,że-XX: Pretenurezethreshold nie jest w ogóle brany pod uwagę.

 3
Author: Arkantos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-08 09:07:26