Wyrzucanie elementów bezużytecznych Java 7 (JDK 7) i dokumentacja na G1

82

Java 7 nie istnieje już od jakiegoś czasu, ale nie mogę znaleźć żadnych dobrych zasobów dotyczących konfiguracji garbage collectorów , a konkretnie nowego kolektora G1 .

Moje pytania:

  1. Czy G1 jest domyślnym kolektorem w Javie 7, a jeśli nie, jak aktywować G1?
  2. Jakie opcjonalne ustawienia ma G1 w Javie7?
  3. Czy wprowadzono jakieś zmiany w innych kolektorach, takich jak cms lub kolektor równoległy w Javie 7?
  4. Gdzie mogę znaleźć dobrą dokumentację dotyczącą czyszczenia pamięci w Javie 7?
Florakel
źródło
6
Rozpoczęcie pracy z G1 Garbage Collector daje również dobry przegląd najlepszych praktyk.
John McCarthy

Odpowiedzi:

47

Moduł odśmiecania pamięci G1 nie jest domyślny w mojej instalacji Javy w wersji 1.7.0_01. Możesz się o tym przekonać, używając dodatkowych opcji wiersza poleceń:

> java -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -version
-XX:InitialHeapSize=132304640 -XX:MaxHeapSize=2116874240 -XX:ParallelGCThreads=4 -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC
java version "1.7.0_01"
Java(TM) SE Runtime Environment (build 1.7.0_01-b08)
Java HotSpot(TM) 64-Bit Server VM (build 21.1-b02, mixed mode)
Heap
 PSYoungGen      total 37696K, used 1293K [0x00000007d5eb0000, 0x00000007d88c0000, 0x0000000800000000)
  eden space 32320K, 4% used [0x00000007d5eb0000,0x00000007d5ff3408,0x00000007d7e40000)
  from space 5376K, 0% used [0x00000007d8380000,0x00000007d8380000,0x00000007d88c0000)
  to   space 5376K, 0% used [0x00000007d7e40000,0x00000007d7e40000,0x00000007d8380000)
 PSOldGen        total 86144K, used 0K [0x0000000781c00000, 0x0000000787020000, 0x00000007d5eb0000)
  object space 86144K, 0% used [0x0000000781c00000,0x0000000781c00000,0x0000000787020000)
 PSPermGen       total 21248K, used 2032K [0x000000077ca00000, 0x000000077dec0000, 0x0000000781c00000)
  object space 21248K, 9% used [0x000000077ca00000,0x000000077cbfc288,0x000000077dec0000)

Nie musisz już włączać opcji eksperymentalnych, aby włączyć kolektor G1:

> java -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseG1GC -version
-XX:InitialHeapSize=132304640 -XX:MaxHeapSize=2116874240 -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseCompressedOops -XX:+UseG1GC -XX:-UseLargePagesIndividualAllocation
java version "1.7.0_01"
Java(TM) SE Runtime Environment (build 1.7.0_01-b08)
Java HotSpot(TM) 64-Bit Server VM (build 21.1-b02, mixed mode)
Heap
 garbage-first heap   total 130048K, used 0K [0x000000077ca00000, 0x0000000784900000, 0x00000007fae00000)
  region size 1024K, 1 young (1024K), 0 survivors (0K)
 compacting perm gen  total 20480K, used 2032K [0x00000007fae00000, 0x00000007fc200000, 0x0000000800000000)
   the space 20480K,   9% used [0x00000007fae00000, 0x00000007faffc288, 0x00000007faffc400, 0x00000007fc200000)
No shared spaces configured.

Nie wiem, gdzie można znaleźć dobrą dokumentację.

Carey
źródło
2
Jest to nadal ważne dla wersji 1.7.0_09 na OSX
Age Mooij
Nie dotyczy Oracle JDK 7u17 na linux / amd64 pobranego bezpośrednio z witryny Oracle. Mówi -XX:+UseParallelGC.
user1050755
31

Oracle w końcu uczyniło G1 oficjalnym w Javie 7 U4: http://www.oracle.com/technetwork/java/javase/7u4-relnotes-1575007.html

Opis: http://docs.oracle.com/javase/7/docs/technotes/guides/vm/G1.html

Opcje wiersza poleceń: http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html#G1Options

Mimo to nie sądzę, aby był to domyślny moduł zbierający w Javie 7. Dla serwerów domyślnym jest Parallel Collector, tak jak w Javie 6.

Florakel
źródło
1
a serwer jest zdefiniowany przez 2 rdzenie i 2 GB pamięci RAM lub więcej. Szczegóły można znaleźć pod adresem hg.openjdk.java.net/jdk7u/jdk7u/hotspot/file/0d82bf449a61/src - spójrz na pliki ./share/tools/launcher/java.c i ./share/vm/runtime/ os.cpp
user1050755
22

Tak, G1 to nowy standardowy moduł odśmiecania pamięci w Javie 1.7 JVM.

Tutaj znajdziesz mnóstwo informacji o tym, jak używać i konfigurować nowy garbage collector:

Korzystanie z G1 G1 jest nadal uważane za eksperymentalne i można je włączyć za pomocą następujących dwóch parametrów:

-XX: + UnlockExperimentalVMOptions -XX: + UseG1GC

Aby ustawić docelowy czas wstrzymania GC, użyj następującego parametru:

-XX: MaxGCPauseMillis = 50 (dla docelowego czasu pauzy 50 ms)

Za pomocą G1 można określić przedział czasu, w którym przerwa GC nie powinna trwać dłużej niż czas podany powyżej:

-XX: GCPauseIntervalMillis = 200 (dla docelowego interwału pauzy 200 ms)

Zauważ, że powyższe dwie opcje reprezentują cele, a nie obietnice lub gwarancje. Mogą działać dobrze w niektórych sytuacjach, ale nie w innych, a GC może nie zawsze być w stanie ich przestrzegać.

Alternatywnie można wyraźnie określić wielkość młodego pokolenia, aby wpłynąć na czas przerwy w ewakuacji:

-XX: + G1YoungGenSize = 512 m (dla młodego pokolenia 512 megabajtów)

G1 używa również odpowiednika przestrzeni ocalałych, które są naturalnie zbiorem (potencjalnie nieciągłych) regionów. Ich rozmiar można określić za pomocą zwykłych parametrów (np. -XX: SurvivorRatio = 6).

Wreszcie, aby uruchomić G1 z pełnym potencjałem, spróbuj ustawić te dwa parametry, które są obecnie domyślnie wyłączone, ponieważ mogą ujawnić rzadki stan wyścigu:

-XX: + G1ParallelRSetUpdatingEnabled -XX: + G1ParallelRSetScanningEnabled

Jeszcze jedną rzeczą wartą uwagi jest to, że G1 jest bardzo gadatliwy w porównaniu z innymi GC HotSpot, gdy ustawiono -XX: + PrintGCDetails. Dzieje się tak, ponieważ drukuje czasy dla wątków GC i inne informacje bardzo pomocne w profilowaniu i rozwiązywaniu problemów. Jeśli chcesz uzyskać bardziej zwięzły dziennik GC, przełącz się na użycie -verbosegc (chociaż zaleca się uzyskanie bardziej szczegółowego dziennika GC).

Uważam również, że ten artykuł jest bardzo pomocny w zrozumieniu wnętrza G1.

Jeszcze więcej informacji tutaj .

Wojtek Owczarczyk
źródło
6
Widziałem te zasoby. Ale pierwszy artykuł dotyczy G1 w JDK 6, kiedy była to jeszcze opcja eksperymentalna. Pozostałe artykuły dotyczą wydań beta JDK 7 i co najmniej 1 rok. Szukam bardziej aktualnych informacji lub oficjalnej dokumentacji od Oracle lub zespołu JDK.
Florakel
13

1. Czy G1 jest domyślnym kolektorem w Javie 7 (...)

Reguła na tej stronie Java 5 nadal ma zastosowanie w Javie 7 (i AFAIK, Java 8):

Na maszynach klasy serwerowej, na których działa maszyna wirtualna serwera, moduł wyrzucania elementów bezużytecznych (GC) został zmieniony z poprzedniego modułu zbierającego dane szeregowe (-XX: + UseSerialGC) na moduł zbierający równoległy (-XX: + UseParallelGC).

Ale rozważ także:

  • 64-bitowe maszyny JVM nie są dostarczane z maszyną -clientwirtualną, więc zawsze są „klasą serwera”
  • Od Java 7, użycie -XX: + UseParallelGC (ustawione lub domniemane) dodatkowo implikuje -XX: + UseParallelOldGC (tj. Chyba że jawnie wyłączone)

Na przykład, jeśli w systemie Windows x64 uruchamiasz ...

  • Java 7 64-bit, domyślnie otrzymujesz Parallel GC (zarówno dla młodych, jak i starszych pokoleń).
  • Java 8 32-bitowa, domyślnie otrzymujesz Serial GC (dla obu generacji)

1. (...) jak aktywować G1?

Od wersji Java 7 po prostu -XX:+UseG1GC. Być może interesujący jest również moment, w którym chciałbyś:

Aplikacje działające obecnie z CMS lub modułem odśmiecania ParallelOld przyniosłyby korzyści z przełączenia na G1, jeśli aplikacja ma co najmniej jedną z następujących cech.

  • Ponad 50% sterty Java jest zajęte przez dane na żywo.
  • Wskaźnik alokacji lub promocji obiektów znacznie się różni.
  • Niepożądane długie przerwy w zbieraniu śmieci lub zagęszczaniu (dłuższe niż 0,5 do 1 sekundy)

2. Jakie opcjonalne ustawienia ma g1 w Javie7?

Sam nie korzystałem z G1, ale wydaje mi się , że jest on zgodny z tymi samymi podstawowymi flagami „przepustowości / ergonomii”, które są używane do strojenia innych równoległych kolektorów. Z mojego doświadczenia z Parallel GC -XX:GCTimeRatiowynika , że był to kluczowy element zapewniający oczekiwany kompromis między szybkością a pamięcią. YMMV.

Tutaj wymieniono opcje specyficzne dla G1

3. Czy nastąpiły zmiany w (...) cms lub kolektorze równoległym w Javie 7?

Nie wiem, ale ...

G1 jest planowany jako długoterminowy zamiennik dla Concurrent Mark-Sweep Collector (CMS)

4. Gdzie mogę znaleźć dobrą dokumentację dotyczącą czyszczenia pamięci w Javie 7?

Znalezienie tego może być trudne, prawda? Prawdopodobnie najlepszą stroną „centrum”, jaką znalazłem, jest ta:

http://www.oracle.com/technetwork/java/javase/tech/index-jsp-140228.html

Wymagana głęboka lektura, ale warto poświęcić czas, jeśli potrzebujesz trochę dostroić. Szczególnie wnikliwa jest: Ergonomia garbage collectora

Luke Usherwood
źródło
13
  1. Czy G1 jest domyślnym kolektorem w Javie 7, a jeśli nie, jak aktywować G1?

G1 nie jest domyślnym kolektorem w Javie 7. -XX:+UseG1GCwłączy G1GC

  1. Jakie opcjonalne ustawienia ma G1 w Javie7?

Jest wiele. Zapoznaj się z tym artykułem w wyroczni, aby uzyskać pełne informacje.

G1 GC to adaptacyjny moduł odśmiecania pamięci z ustawieniami domyślnymi, które umożliwiają wydajną pracę bez modyfikacji.

Z tego powodu dostosuj krytyczne parametry

-XX:MaxGCPauseMillis
-XX:G1HeapRegionSize
-XX:ParallelGCThreads
-XX:ConcGCThreads

i pozostaw wszystkim innym parametrom wartość domyślną .

Oto lista ważnych opcji i ich wartości domyślnych. Ta lista dotyczy najnowszej maszyny wirtualnej Java HotSpot, kompilacja 24. Możesz dostosować i dostroić ustawienia G1 GC w wierszu poleceń maszyny JVM.

Ważne wartości domyślne:

-XX:G1HeapRegionSize=n

Ustawia rozmiar regionu G1. Wartość będzie potęgą dwóch i może wynosić od 1 MB do 32 MB. Celem jest posiadanie około 2048 regionów w oparciu o minimalny rozmiar sterty Java.

-XX:MaxGCPauseMillis=200

Ustawia wartość docelową dla żądanego maksymalnego czasu przerwy. Wartość domyślna to 200 milisekund. Podana wartość nie dostosowuje się do rozmiaru sterty.

-XX:G1NewSizePercent=5

Ustawia procent sterty, który ma być używany jako minimum dla rozmiaru młodego pokolenia. Wartość domyślna to 5 procent stosu Java.

-XX:G1MaxNewSizePercent=60

Ustawia procent rozmiaru sterty, który ma być używany jako maksymalny dla rozmiaru młodego pokolenia. Wartość domyślna to 60 procent stosu Java.

-XX:ParallelGCThreads=n

Ustawia wartość wątków roboczych STW. Ustawia wartość n na liczbę procesorów logicznych. Wartość n jest taka sama, jak liczba procesorów logicznych, aż do wartości 8.

Jeśli jest więcej niż osiem procesorów logicznych, ustawia wartość n na około 5/8 procesorów logicznych. Działa to w większości przypadków, z wyjątkiem większych systemów SPARC, w których wartość n może wynosić około 5/16 procesorów logicznych.

-XX:ConcGCThreads=n

Ustawia liczbę równoległych gwintów znakujących. Ustawia n na około 1/4 liczby równoległych wątków wyrzucania elementów bezużytecznych (ParallelGCThreads).

-XX:InitiatingHeapOccupancyPercent=45

Ustawia próg zajętości sterty Java, który wyzwala cykl znakowania. Domyślne zajęcie wynosi 45 procent całej sterty Java.

-XX:G1MixedGCLiveThresholdPercent=65

Ustawia próg zajętości dla starego regionu, który ma być uwzględniony w mieszanym cyklu wyrzucania elementów bezużytecznych. Domyślne obłożenie to 65 procent

-XX:G1HeapWastePercent=10

Ustawia procent sterty, który chcesz zmarnować. Maszyna wirtualna Java HotSpot nie inicjuje cyklu mieszanego wyrzucania elementów bezużytecznych, gdy procent do odzyskania jest mniejszy niż procent marnotrawstwa sterty

-XX:G1MixedGCCountTarget=8

Ustawia docelową liczbę mieszanych operacji wyrzucania elementów bezużytecznych po cyklu znakowania w celu zebrania starych regionów z maksymalnie G1MixedGCLIveThresholdPercent danymi na żywo. Wartość domyślna to 8 mieszanych kolekcji elementów bezużytecznych

-XX:G1OldCSetRegionThresholdPercent=10

Ustawia górny limit liczby starych regionów do zebrania podczas mieszanego cyklu wyrzucania elementów bezużytecznych. Wartość domyślna to 10 procent sterty Java

-XX:G1ReservePercent=10

Ustawia procent wolnej pamięci rezerwowej, aby zmniejszyć ryzyko przepełnienia przestrzeni. Wartość domyślna to 10 procent. Zwiększając lub zmniejszając wartość procentową, pamiętaj o dopasowaniu całkowitej sterty Java o tę samą wartość.

Ponownie skonfigurowałeś wiele parametrów G1GC, które nie są wymagane, jeśli postępujesz zgodnie z powyższą stroną dokumentacji. Proszę sprawdzić krzyżowo powyższe zalecenia, zwłaszcza dotyczące ParallelGCThreads i ConcGCThreads , które mają być oparte na rdzeniach procesora. Usuń zmianę konfiguracji niepotrzebnych parametrów.

Zalecenia firmy Oracle:

Podczas oceniania i dostrajania G1 GC, pamiętaj o następujących zaleceniach:

  1. Wielkość młodego pokolenia : Unikaj jawnego określania wielkości młodego pokolenia za pomocą -Xmnopcji lub jakiejkolwiek innej powiązanej opcji, takiej jak -XX:NewRatio. Ustalenie wielkości młodego pokolenia unieważnia docelowy czas przerwy .

  2. Cele czasowe wstrzymania: podczas oceny lub dostrajania dowolnego wyrzucania elementów bezużytecznych zawsze występuje kompromis między opóźnieniem a przepustowością. G1 GC to przyrostowy moduł wyrzucania elementów bezużytecznych z jednolitymi przerwami, ale także z większym obciążeniem wątków aplikacji. Celem przepustowości dla G1 GC jest 90 procent czasu aplikacji i 10 procent czasu usuwania elementów bezużytecznych .

  1. Czy wprowadzono jakieś zmiany w innych kolektorach, takich jak cms lub kolektor równoległy w Javie 7?

W Javie 7 nastąpiły pewne zmiany. Przeczytaj ten artykuł

  1. Gdzie mogę znaleźć dobrą dokumentację dotyczącą czyszczenia pamięci w Javie 7?

Zapoznaj się ze stroną dokumentacji Oracle dotyczącą gc i powiązanego pytania SE:

Wybieranie elementów bezużytecznych Java G1 w środowisku produkcyjnym

Ravindra babu
źródło
3

Żaden G1 nie jest domyślnym garbage collectorem w jdk 1.7.0_02. Domyślny moduł odśmiecania pamięci zależy od klasy maszyny. Jeśli maszyna należy do klasy serwera, domyślnym modułem odśmiecania pamięci jest moduł przetwarzania przepustowości. Jeśli maszyna jest klasy Client, domyślnym modułem odśmiecania pamięci jest Serial Collector.

Nitan S. Kotwal
źródło
1
Zaprzeczam, że jest to całkowicie poprawne. Dokumentacja Java 5 , nadal ważna. W systemie Windows (32/64): Domyślnie uruchom środowisko Java w wersji 32-bitowej (5–8) >> Serial GC. Domyślnie uruchom Java 64-bit (5..6) >> ParallelGC (tylko Young gen). Domyślnie uruchom Java 64-bit (7..8) >> ParallelOldGC (równolegle Young i Old). Odniesienie do zmiany Java 7 , wreszcie kolektor „równoległy” == kolektor przepustowości ”
Luke Usherwood
3
(Ostra odpowiedź na pierwszy i dokładny wkład tej osoby. Zauważam, że jest to również ich ostatni.)
Luke Usherwood,
2

Dokumentacja dostępna pod adresem http://www.oracle.com/technetwork/java/javase/tech/g1-intro-jsp-135488.html (link udostępniony przez Wojtka) wydaje się być jedynym oficjalnym linkiem zawierającym informacje, ale informacje wydaje się przestarzały, ponieważ niektóre z wymienionych flag były dostępne tylko w wersjach testowych i nie istnieją już w wersjach produkcyjnych. Ktoś z firmy Oracle powinien dostarczyć zaktualizowaną dokumentację dotyczącą G1 GC.

Lodziarz
źródło
0

Domyślnie nie chcesz używać kolektora G1, ponieważ nie jest lepszy od innych. Nadaje się tylko do specjalnych celów.

W przypadku małych opóźnień aplikacja jest nieco lepsza niż CMS, ponieważ ma nieco krótsze i bardziej przewidywalne czasy wstrzymania. W zamian przepustowość jest znacznie gorsza niż CMS w zamian.

Więc jest dobre tylko wtedy, gdy opóźnienie jest ważne, ale przepustowość nie jest wcale ważna. Jeśli oba są ważne, pozostań przy CMS.

Zoltan Juhasz
źródło