Garbage Collection und Dokumentation für Java 7 (JDK 7) auf G1

81

Java 7 ist schon eine Weile nicht mehr verfügbar, aber ich kann keine guten Ressourcen für die Konfiguration der Garbage Collectors finden , insbesondere des neuen G1-Collectors .

Meine Fragen:

  1. Ist G1 der Standardkollektor in Java 7 und wenn nicht, wie aktiviere ich G1?
  2. Welche optionalen Einstellungen hat g1 in Java7?
  3. Wurden Änderungen an anderen Kollektoren wie cms oder dem Parallelkollektor in Java 7 vorgenommen?
  4. Wo finde ich eine gute Dokumentation zur Garbage Collection in Java 7?
Florakel
quelle
6
Erste Schritte mit dem G1 Garbage Collector bieten auch einen guten Überblick über Best Practices.
John McCarthy

Antworten:

47

Der G1-Garbage Collector ist nicht die Standardeinstellung in meiner Java-Installation, Version 1.7.0_01. Sie können sich selbst davon überzeugen, indem Sie einige zusätzliche Befehlszeilenoptionen verwenden:

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

Sie müssen jedoch keine experimentellen Optionen mehr aktivieren, um den G1-Kollektor einzuschalten:

> 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.

Ich weiß nicht, wo Sie eine gute Dokumentation finden können.

Carey
quelle
2
Dies gilt immer noch für 1.7.0_09 unter OSX
Age Mooij
1
Gleiches am 1.7.0_10 unter Linux
Marc Polizzi
Nicht zutreffend für Oracle JDK 7u17 unter Linux / amd64, das direkt von der Oracle-Website abgerufen wird. Es heißt -XX:+UseParallelGC.
user1050755
31

Oracle hat G1 schließlich in Java 7 U4 offiziell gemacht: http://www.oracle.com/technetwork/java/javase/7u4-relnotes-1575007.html

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

Befehlszeilenoptionen: http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html#G1Options

Ich glaube jedoch nicht, dass dies der Standardkollektor in Java 7 ist. Für Server ist der Standardkollektor wie in Java 6 der Standardkollektor.

Florakel
quelle
1
und der Server wird durch 2 Kerne und 2 GB RAM oder mehr definiert. Details finden Sie unter hg.openjdk.java.net/jdk7u/jdk7u/hotspot/file/0d82bf449a61/src - sehen Sie sich die Dateien ./share/tools/launcher/java.c und ./share/vm/runtime/ an. os.cpp
user1050755
22

Ja, G1 ist der neue Standard-Garbage Collector in Java 1.7 JVM.

Hier finden Sie zahlreiche Informationen zur Verwendung und Konfiguration des neuen Garbage Collector:

Die Verwendung von G1 G1 gilt weiterhin als experimentell und kann mit den folgenden zwei Parametern aktiviert werden:

-XX: + UnlockExperimentalVMOptions -XX: + UseG1GC

Verwenden Sie den folgenden Parameter, um ein Ziel für die GC-Pausenzeit festzulegen:

-XX: MaxGCPauseMillis = 50 (für ein Pausenzeitziel von 50 ms)

Mit G1 kann ein Zeitintervall festgelegt werden, in dem eine GC-Pause nicht länger als die oben angegebene Zeit dauern soll:

-XX: GCPauseIntervalMillis = 200 (für ein Pausenintervallziel von 200 ms)

Beachten Sie, dass die beiden oben genannten Optionen Ziele darstellen, keine Versprechen oder Garantien. In einigen Situationen funktionieren sie möglicherweise gut, in anderen jedoch nicht, und der GC kann ihnen möglicherweise nicht immer gehorchen.

Alternativ kann die Größe der jungen Generation explizit angegeben werden, um die Evakuierungspausenzeiten zu beeinflussen:

-XX: + G1YoungGenSize = 512 m (für eine junge Generation mit 512 Megabyte)

G1 verwendet auch das Äquivalent von Überlebensräumen, bei denen es sich natürlich um eine Reihe von (möglicherweise nicht zusammenhängenden) Regionen handelt. Ihre Größe kann mit den üblichen Parametern angegeben werden (z. B. -XX: SurvivorRatio = 6).

Um G1 voll auszuschöpfen, versuchen Sie schließlich, diese beiden Parameter einzustellen, die derzeit standardmäßig deaktiviert sind, da sie möglicherweise eine seltene Rennbedingung aufdecken:

-XX: + G1ParallelRSetUpdatingEnabled -XX: + G1ParallelRSetScanningEnabled

Eine weitere zu beachtende Sache ist, dass G1 im Vergleich zu anderen HotSpot-GCs sehr ausführlich ist, wenn -XX: + PrintGCDetails eingestellt ist. Dies liegt daran, dass Timings pro GC-Thread und andere Informationen gedruckt werden, die bei der Profilerstellung und Fehlerbehebung sehr hilfreich sind. Wenn Sie ein präziseres GC-Protokoll wünschen, wechseln Sie bitte zu -verbosegc (es wird jedoch empfohlen, das detailliertere GC-Protokoll zu erhalten).

Ich fand diesen Artikel auch sehr hilfreich, um die Innereien von G1 zu verstehen.

Noch mehr Infos hier .

Wojtek Owczarczyk
quelle
6
Ich habe diese Ressourcen gesehen. Der erste Artikel handelt jedoch von G1 in JDK 6, als es noch eine experimentelle Option war. Die anderen Artikel befassen sich mit Beta-Versionen des JDK 7 und sind mindestens 1 Jahr alt. Ich suche nach aktuelleren Informationen oder offiziellen Unterlagen von Oracle oder dem JDK-Team.
Florakel
13

1. Ist G1 der Standardkollektor in Java 7 (...)

Die Regel auf dieser Java 5-Seite gilt weiterhin in Java 7 (und AFAIK, Java 8):

Auf dem Server-Klasse Maschinen VM den Server ausgeführt wird , die Garbage Collector (GC) wird aus dem vorherigen seriellen Kollektor verändert (-XX: + UseSerialGC) zu einem parallelen Kollektor (-XX: + UseParallelGC).

Aber bedenken Sie auch:

  • 64-Bit-JVMs werden nicht mit einer -clientVM geliefert und sind daher immer "Serverklasse".
  • Seit Java 7 impliziert die Verwendung von -XX: + UseParallelGC (ob gesetzt oder impliziert) zusätzlich -XX: + UseParallelOldGC (dh sofern nicht ausdrücklich deaktiviert).

Wenn Sie beispielsweise unter Windows x64 ausführen ...

  • In Java 7 64-Bit erhalten Sie standardmäßig Parallel GC (für junge und alte Generationen).
  • In Java 8 32-Bit erhalten Sie standardmäßig Serial GC (für beide Generationen)

1. (...) wie aktiviere ich G1?

Ab Java 7 einfach -XX:+UseG1GC. Vielleicht ist auch von Interesse, wenn Sie möchten:

Anwendungen, die heute entweder mit dem CMS oder dem ParallelOld-Garbage Collector ausgeführt werden, würden von einem Wechsel zu G1 profitieren, wenn die Anwendung eine oder mehrere der folgenden Eigenschaften aufweist.

  • Mehr als 50% des Java-Heaps sind mit Live-Daten belegt.
  • Die Rate der Objektzuweisungsrate oder der Promotion variiert erheblich.
  • Unerwünschte lange Speicherbereinigungs- oder Verdichtungspausen (länger als 0,5 bis 1 Sekunde)

2. Welche optionalen Einstellungen hat g1 in Java7?

Ich habe G1 selbst nicht verwendet, aber ich stelle fest, dass es denselben grundlegenden "Durchsatz / Ergonomie" -Flaggen entspricht, die zum Abstimmen der anderen parallelen Kollektoren verwendet wurden. Nach meiner Erfahrung mit dem Parallel GC war -XX:GCTimeRatiodies der entscheidende Faktor für den erwarteten Kompromiss zwischen Geschwindigkeit und Speicher. YMMV.

G1-spezifische Optionen sind hier aufgelistet

3. Gab es Änderungen an (...) cms oder dem Parallelkollektor in Java 7?

Weiß nicht, aber ...

G1 ist als langfristiger Ersatz für den Concurrent Mark-Sweep Collector (CMS) geplant.

4. Wo finde ich eine gute Dokumentation zur Garbage Collection in Java 7?

Es kann schmerzhaft sein, es zu finden, nicht wahr? Die wahrscheinlich beste "Hub" -Seite, die ich gefunden habe, ist diese:

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

Einige gründliche Lektüre erforderlich, aber die Zeit lohnt sich, wenn Sie etwas tunen müssen. Besonders aufschlussreich ist: Garbage Collector Ergonomics

Luke Usherwood
quelle
13
  1. Ist G1 der Standardkollektor in Java 7 und wenn nicht, wie aktiviere ich G1?

G1 ist in Java 7 kein Standardkollektor. -XX:+UseG1GCG1GC wird aktiviert

  1. Welche optionalen Einstellungen hat g1 in Java7?

Es gibt viele. In diesem Orakelartikel finden Sie vollständige Informationen.

Der G1 GC ist ein adaptiver Garbage Collector mit Standardeinstellungen, die es ihm ermöglichen, ohne Änderungen effizient zu arbeiten.

Passen Sie aus diesem Grund kritische Parameter an

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

und belassen Sie alle anderen Parameter auf dem Standardwert .

Hier finden Sie eine Liste wichtiger Optionen und ihrer Standardwerte. Diese Liste gilt für die neueste Java HotSpot-VM, Build 24. Sie können die G1 GC-Einstellungen in der JVM-Befehlszeile anpassen und optimieren.

Wichtige Standardeinstellungen:

-XX:G1HeapRegionSize=n

Legt die Größe einer G1-Region fest. Der Wert ist eine Zweierpotenz und kann zwischen 1 MB und 32 MB liegen. Das Ziel ist es, ungefähr 2048 Regionen basierend auf der minimalen Java-Heap-Größe zu haben.

-XX:MaxGCPauseMillis=200

Legt einen Zielwert für die gewünschte maximale Pausenzeit fest. Der Standardwert ist 200 Millisekunden. Der angegebene Wert passt sich nicht an Ihre Heap-Größe an.

-XX:G1NewSizePercent=5

Legt den Prozentsatz des Heaps fest, der als Minimum für die Größe der jungen Generation verwendet werden soll. Der Standardwert beträgt 5 Prozent Ihres Java-Heaps.

-XX:G1MaxNewSizePercent=60

Legt den Prozentsatz der Heap-Größe fest, der als Maximum für die Größe der jungen Generation verwendet werden soll. Der Standardwert beträgt 60 Prozent Ihres Java-Heaps.

-XX:ParallelGCThreads=n

Legt den Wert der STW-Arbeitsthreads fest. Setzt den Wert von n auf die Anzahl der logischen Prozessoren. Der Wert von n entspricht der Anzahl der logischen Prozessoren bis zu einem Wert von 8.

Wenn mehr als acht logische Prozessoren vorhanden sind, wird der Wert von n auf ungefähr 5/8 der logischen Prozessoren festgelegt. Dies funktioniert in den meisten Fällen mit Ausnahme größerer SPARC-Systeme, bei denen der Wert von n ungefähr 5/16 der logischen Prozessoren betragen kann.

-XX:ConcGCThreads=n

Legt die Anzahl der parallelen Markierungsfäden fest. Setzt n auf ungefähr 1/4 der Anzahl paralleler Garbage Collection-Threads (ParallelGCThreads).

-XX:InitiatingHeapOccupancyPercent=45

Legt den Java-Heap-Belegungsschwellenwert fest, der einen Markierungszyklus auslöst. Die Standardbelegung beträgt 45 Prozent des gesamten Java-Heaps.

-XX:G1MixedGCLiveThresholdPercent=65

Legt den Belegungsschwellenwert für eine alte Region fest, die in einen gemischten Speicherbereinigungszyklus aufgenommen werden soll. Die Standardbelegung beträgt 65 Prozent

-XX:G1HeapWastePercent=10

Legt den Prozentsatz des Heaps fest, den Sie verschwenden möchten. Die Java HotSpot-VM initiiert den gemischten Speicherbereinigungszyklus nicht, wenn der Prozentsatz der zurückfordernden Daten weniger als der Prozentsatz der Heap-Verschwendung ist

-XX:G1MixedGCCountTarget=8

Legt die Zielanzahl gemischter Speicherbereinigungen nach einem Markierungszyklus fest, um alte Regionen mit höchstens G1MixedGCLIveThresholdPercent-Live-Daten zu erfassen. Der Standardwert ist 8 gemischte Speicherbereinigungen

-XX:G1OldCSetRegionThresholdPercent=10

Legt eine Obergrenze für die Anzahl alter Regionen fest, die während eines gemischten Speicherbereinigungszyklus gesammelt werden sollen. Der Standardwert beträgt 10 Prozent des Java-Heaps

-XX:G1ReservePercent=10

Legt den Prozentsatz des Reservespeichers fest, der frei bleibt, um das Risiko von Überläufen zum Speicherplatz zu verringern. Der Standardwert beträgt 10 Prozent. Stellen Sie beim Erhöhen oder Verringern des Prozentsatzes sicher, dass der gesamte Java-Heap um denselben Betrag angepasst wird.

Sie haben viele G1GC-Parameter neu konfiguriert, die nicht erforderlich sind, wenn Sie der obigen Dokumentationsseite folgen. Bitte überprüfen Sie die obigen Empfehlungen, insbesondere für ParallelGCThreads und ConcGCThreads , die auf Ihren CPU-Kernen basieren sollen. Entfernen Sie die Neukonfiguration nicht benötigter Parameter.

Empfehlungen von Orakel:

Beachten Sie bei der Bewertung und Feinabstimmung von G1 GC die folgenden Empfehlungen:

  1. Größe der jungen Generation : Vermeiden Sie es, die Größe der jungen Generation explizit mit der -XmnOption oder einer anderen verwandten Option wie z -XX:NewRatio. Das Festlegen der Größe der jungen Generation überschreibt das Ziel der Pausenzeit .

  2. Pausenzeitziele: Wenn Sie eine Garbage Collection auswerten oder optimieren, gibt es immer einen Kompromiss zwischen Latenz und Durchsatz. Der G1 GC ist ein inkrementeller Garbage Collector mit einheitlichen Pausen, aber auch mehr Overhead für die Anwendungsthreads. Das Durchsatzziel für den G1 GC liegt bei 90 Prozent Anwendungszeit und 10 Prozent Speicherbereinigungszeit .

  1. Wurden Änderungen an anderen Kollektoren wie cms oder dem Parallelkollektor in Java 7 vorgenommen?

Es gibt einige Änderungen mit Java 7. Schauen Sie sich diesen Artikel an

  1. Wo finde ich eine gute Dokumentation zur Garbage Collection in Java 7?

Siehe Oracle-Dokumentationsseite zu gc und verwandten SE-Fragen:

Java G1 Garbage Collection in der Produktion

Ravindra Babu
quelle
3

Nein G1 ist kein Standard-Garbage Collector in jdk 1.7.0_02. Der Standard-Garbage Collector hängt von der Maschinenklasse ab. Wenn der Computer der Serverklasse angehört, ist der Standard-Garbage Collector der Throughput Collector. Wenn der Computer der Client-Klasse angehört, ist der Standard-Garbage-Collector Serial Collector.

Nitan S. Kotwal
quelle
1
Ich bestreite, dass dies völlig richtig ist. Java 5-Referenz , noch gültig. Auf einem Windows-System (32/64): Führen Sie standardmäßig Java 32-Bit (5..8) >> Serial GC aus. Führen Sie Java 64-Bit (5..6) >> ParallelGC (nur Young Gen) standardmäßig aus. Führen Sie Java 64-Bit (7..8) >> ParallelOldGC (parallel Jung und Alt) standardmäßig aus. Referenz für Java 7 ändern , schließlich 'paralleler' Kollektor == 'Durchsatz' Kollektor "
Luke Usherwood
3
(Eine harte Antwort auf den ersten und genauen SO-Beitrag dieser Person. Ich stelle fest, dass es auch ihr letzter ist.)
Luke Usherwood
2

Die Dokumentation unter http://www.oracle.com/technetwork/java/javase/tech/g1-intro-jsp-135488.html (der von Wojtek bereitgestellte Link) scheint der einzige offizielle Link mit Informationen zu sein, aber den Informationen scheint veraltet zu sein, da einige der dort genannten Flags nur in den Test-Builds verfügbar waren und in den Produktionsversionen nicht mehr vorhanden sind. Jemand von Oracle sollte eine aktualisierte Dokumentation zum G1 GC bereitstellen.

IceMan
quelle
0

Standardmäßig möchten Sie den G1-Kollektor nicht wirklich verwenden, da er nicht wirklich besser ist als die anderen. Es ist nur für spezielle Zwecke gut.

Bei geringer Latenz ist die Anwendung etwas besser als bei CMS, da sie etwas kürzere und vorhersehbarere Pausenzeiten aufweist. Im Gegenzug ist der Durchsatz viel schlechter als bei CMS.

Es ist also nur gut, wenn die Latenz wichtig ist, aber der Durchsatz überhaupt nicht wichtig ist. Wenn beide wichtig sind, bleiben Sie bei CMS.

Zoltan Juhasz
quelle