Heim  >  Artikel  >  Java  >  Parsen des Java G1 Garbage Collectors

Parsen des Java G1 Garbage Collectors

怪我咯
怪我咯Original
2017-04-05 16:24:391477Durchsuche

Dieser Artikel stellt zunächst kurz die gängigen Methoden der Garbage Collection vor, analysiert dann das Sammelprinzip des G1-Collectors, seine Vorteile im Vergleich zu anderen Garbage Collectors und gibt schließlich einige Optimierungspraktiken.

1. Was ist Garbage Collection?

Bevor wir G1 verstehen, müssen wir zunächst genau wissen, was Garbage Collection ist. Einfach ausgedrückt besteht die Garbage Collection darin, Objekte zu recyceln, die nicht mehr im Speicher verwendet werden.

Grundlegende Schritte der Müllsammlung

Es gibt 2 Schritte beim Recycling:

  1. Objekte finden, die nicht mehr im Speicher verwendet werden

  2. Gib den von diesen Objekten belegten Speicher frei

1. Finde Objekte, die nicht mehr im Speicher verwendet werden

Dann stellt sich die Frage, wie man das ermittelt Welche Objekte werden nicht mehr verwendet? Wenn auf ein Objekt kein Verweis verweist, kann es als Müll betrachtet werden. Der Nachteil dieser Methode besteht darin, dass sie die Existenz des Rings nicht erkennen kann

    Die Grundidee des Root-Suchalgorithmus besteht darin, eine Reihe von Objekten mit dem Namen „GC Roots“ als Ausgangspunkt zu verwenden, ausgehend von diesen Knoten und nach unten zu suchen wird als Referenzkette bezeichnet. Wenn ein Objekt keine mit GC Roots verbundene Referenzkette hat, ist bewiesen, dass dieses Objekt nicht verfügbar ist. Wie können wir diese Objekte bereinigen? 2. Geben Sie den von diesen Objekten belegten Speicher frei
  1. Übliche Methoden umfassen Kopieren oder direktes Bereinigen, aber das direkte Bereinigen führt zu einer Speicherfragmentierung, sodass die Reinigungs- und Komprimierungsmethode erzeugt wird Im Allgemeinen gilt: Es gibt drei Arten von Recycling-Algorithmen. 🎜>

    1. Mark-Copy
Es teilt die verfügbare Speicherkapazität in zwei gleich große Blöcke auf und verwendet jeweils nur einen davon 🎜>Kopieren Sie das Objekt

in einen anderen Block und löschen Sie dann den verwendeten Speicherplatz. Der Nachteil ist die einfache Implementierung, die hohe Effizienz und die fehlende Speicherfragmentierung dass zur Verwaltung das Doppelte des Speichers erforderlich ist.

2. Der Markierungs- und Löschalgorithmus ist in zwei Stufen unterteilt: „Markieren“ und „Löschen“. Die Objekte, die recycelt werden müssen, und die Objekte nach Abschluss der Markierung gleichmäßig gelöscht werden, sind jedoch anfällig für Speicherfragmentierung

3 🎜>

Der Markierungsvorgang entspricht dem „Mark-Clean“-Algorithmus. Der nachfolgende Vorgang besteht nicht nur darin, das Objekt direkt zu bereinigen, sondern nach dem Bereinigen nutzloser Objekte werden alle verbleibenden Objekte an ein Ende verschoben und die Zeiger referenziert Da die Objekte aktualisiert werden, ist dies weniger effizient als „Mark-Clean“, aber es erzeugt keine Speicherfragmentierung.

Seit dem Überleben Die Zeit von Objekten ist lang und kurz. Bei Objekten mit langer Überlebenszeit kann durch die Reduzierung der GC-Zeit unnötiger Overhead vermieden werden. Der Speicher wird in die neue Generation und die alte Generation unterteilt eine relativ kurze Überlebenszeit, und die alte Generation speichert Objekte mit einer relativ langen Überlebenszeit. Auf diese Weise wird jedes Mal nur die junge Generation gereinigt, und die alte Generation wird nur bei Bedarf gereinigt, was die GC-Effizienz erheblich verbessern und GC-Zeit sparen kann.

Geschichte des Java Garbage Collectors

Die erste Stufe, Serial Collector

Vor jdk1.3.1 konnte die Java Virtual Machine nur den Serial Collector verwenden. Der serielle Kollektor ist ein Single-Threaded-Kollektor, aber seine Bedeutung „Single-Threaded“ bedeutet nicht nur, dass er nur eine CPU oder einen Sammelthread verwendet, um die Garbage-Collection-Arbeit abzuschließen, sondern, was noch wichtiger ist, er verwendet nur eine CPU bzw Ein Sammelthread muss die Garbage-Collection-Arbeit abschließen, alle anderen Arbeitsthreads müssen angehalten werden, bis die Sammlung abgeschlossen ist.

PS: So aktivieren Sie den seriellen Kollektor

-XX:+UseSerialGC

Zweite Stufe, paralleler (paralleler) Kollektor

Parallelkollektor Auch bekannt Als Durchsatzkollektor besteht der Hauptvorteil von Parallel im Vergleich zum seriellen Kollektor in der Verwendung von Multithreads zur Vervollständigung der Müllbereinigungsarbeit, wodurch die Eigenschaften von Multicore voll ausgenutzt und die GC-Zeit erheblich verkürzt werden können.

PS: So aktivieren Sie den Parallel-Kollektor

-XX:+UseParallelGC -XX:+UseParallelOldGC

Die dritte Stufe, CMS (gleichzeitiger) Kollektor

Der CMS-Collector pausiert alle Anwendungsthreads während der Minor GC und führt die Garbage Collection im Multithread-Verfahren durch. Während der vollständigen GC wird der Anwendungsthread nicht mehr angehalten. Stattdessen werden mehrere Hintergrundthreads verwendet, um den Speicherplatz der alten Generation regelmäßig zu scannen und darin nicht mehr verwendete Objekte rechtzeitig zu recyceln.

PS: So aktivieren Sie den CMS-Kollektor

-XX:+UseParNewGC -XX:+UseConcMarkSweepGC

Die vierte Stufe, G1-Kollektor (gleichzeitig)

Der G1-Kollektor (oder Garbage-First-Kollektor) ist darauf ausgelegt, Pausen bei der Verarbeitung sehr großer Heaps (größer als 4 GB) zu minimieren. Der Vorteil gegenüber CMS besteht darin, dass die Erzeugungsrate der Speicherfragmentierung stark reduziert wird.

PS: So aktivieren Sie den G1-Kollektor

-XX:+UseG1GC

Zweitens: G1 verstehen

Das erste Papier (Anhang 1) von G1 wurde 2004 veröffentlicht und war 2012 nur in jdk1.7u4 verfügbar. Oracle plant offiziell, G1 in jdk9 zum Standard-Garbage Collector zu machen, um CMS zu ersetzen. Warum empfiehlt Oracle dringend G1? Was sind die Vorteile von G1?

Zuallererst ist das Designprinzip von G1 eine einfache und realisierbare Leistungsoptimierung

Entwickler müssen lediglich die folgenden Parameter deklarieren:

-XX: + UseG1GC -Xmx32g -XX:MaxGCPauseMillis=200

Unter ihnen -XX:+UseG1GC dient zum Einschalten des G1-Garbage Collectors, -Xmx32g Der maximale Speicher des entworfenen Heap-Speichers beträgt 32G, -XX:MaxGCPauseMillis=200 legt den maximalen GC fest. Die Pausenzeit beträgt 200 ms. Wenn wir eine Optimierung durchführen müssen und die Speichergröße sicher ist, müssen wir nur die maximale Pausenzeit ändern.

Zweitens hebt G1 die physische Raumteilung zwischen der neuen und der alten Generation auf.

Auf diese Weise müssen wir nicht mehr jede Generation in einem separaten Raum einrichten und müssen uns keine Gedanken darüber machen, ob für jede Generation genügend Speicher vorhanden ist.

Parsen des Java G1 Garbage Collectors

Stattdessen unterteilt der G1-Algorithmus den Heap in mehrere Regionen (Regions), die weiterhin zum Generationssammler gehören. Einige dieser Bereiche umfassen jedoch auch in der neuen Generation die Methode, alle Anwendungsthreads anzuhalten und überlebende Objekte in den Survivor-Bereich der alten Generation zu kopieren. Auch die alte Generation ist in viele Bereiche unterteilt, und der G1-Kollektor erledigt die Aufräumarbeiten, indem er Objekte von einem Bereich in einen anderen kopiert. Dies bedeutet, dass G1 während der normalen Verarbeitung die Komprimierung des Heaps (zumindest eines Teils des Heaps) abschließt, sodass kein Problem mit der Fragmentierung des CMS-Speichers auftritt.

Parsen des Java G1 Garbage Collectors

In G1 gibt es auch einen speziellen Bereich namens Humongous-Bereich. Wenn ein Objekt mehr als 50 % der Partitionskapazität einnimmt, betrachtet der G1-Kollektor es als Riesenobjekt. Diese Riesenobjekte werden standardmäßig direkt in der alten Generation zugewiesen. Wenn es sich jedoch um kurzlebige Riesenobjekte handelt, wirkt sich dies negativ auf den Garbage Collector aus. Um dieses Problem zu lösen, teilt G1 einen Humongous-Bereich auf, der zur Lagerung riesiger Objekte verwendet wird. Wenn ein großes Objekt nicht in eine H-Partition passt, sucht G1 nach einer zusammenhängenden H-Partition, um es zu speichern. Um den kontinuierlichen H-Bereich zu finden, muss manchmal die vollständige GC gestartet werden.

PS: In Java 8 wurde auch die persistente Generation in den gewöhnlichen Heap-Speicherraum verschoben und in den Metaraum geändert.

Objektzuteilungsstrategie

Wenn wir von der Zuteilung großer Objekte sprechen, müssen wir über die Objektzuteilungsstrategie sprechen. Es ist in 3 Stufen unterteilt:

  1. TLAB (Thread Local Allocation Buffer) Thread-Lokalzuordnungspuffer

  2. Zuordnung im Eden-Bereich

  3. Riesige Bereichszuweisung

TLAB weist lokal Puffer für Threads zu. Sein Zweck besteht darin, Objekte so schnell wie möglich zuzuweisen. Wenn Objekte in einem gemeinsam genutzten Bereich zugewiesen werden, müssen wir einen Synchronisierungsmechanismus verwenden, um Zeiger auf freien Speicherplatz in diesen Bereichen zu verwalten. Im Eden-Raum verfügt jeder Thread über eine feste Partition zum Zuweisen von Objekten, also ein TLAB. Beim Zuweisen von Objekten ist keine Synchronisierung zwischen Threads erforderlich.

Bei Objekten, die nicht im TLAB-Raum zugewiesen werden können, versucht die JVM, sie im Eden-Raum zuzuweisen. Wenn der Eden-Raum das Objekt nicht aufnehmen kann, kann der Platz nur in der alten Generation zugewiesen werden.

Schließlich bietet G1 zwei GC-Modi, Young GC und Mixed GC, die beide Stop The World (STW) sind. Im Folgenden werden wir diese beiden Modi jeweils vorstellen.

Drei, G1 Young GC

Young GC führt GC hauptsächlich im Eden-Bereich durch, der ausgelöst wird, wenn der Eden-Raum erschöpft ist. In diesem Fall werden die Daten im Eden-Raum in den Survivor-Raum verschoben. Wenn der Survivor-Raum nicht ausreicht, wird ein Teil der Daten im Eden-Raum direkt in den Raum der alten Generation verschoben. Die Daten im Survivor-Bereich werden in den neuen Survivor-Bereich verschoben, und einige Daten werden auch in den Bereich der alten Generation hochgestuft. Schließlich sind die Daten im Eden-Raum leer, der GC funktioniert nicht mehr und der Anwendungsthread wird weiterhin ausgeführt.

Parsen des Java G1 Garbage Collectors

Parsen des Java G1 Garbage Collectors

Zu diesem Zeitpunkt müssen wir uns eine Frage stellen, wenn wir nur die Objekte der neuen Generation GC finden Root-Objekte? Sind alle Objekte in der alten Generation verwurzelt? Ein solcher Scan wird viel Zeit in Anspruch nehmen. Daher führte G1 das Konzept von RSet ein. Sein vollständiger Name ist Remembered Set und seine Funktion besteht darin, Objektreferenzen zu verfolgen, die auf einen bestimmten Heap-Bereich verweisen.

Parsen des Java G1 Garbage Collectors

Im CMS gibt es auch das Konzept von RSet. Es gibt einen Bereich in der alten Generation, um Verweise auf die neue Generation aufzuzeichnen. Dies ist ein Hinweis darauf, dass bei der Durchführung von Young GC beim Scannen des Stamms nur dieser Bereich gescannt werden muss und nicht die gesamte alte Generation gescannt werden muss.

In G1 wird Point-Out jedoch nicht verwendet. Dies liegt daran, dass eine Partition zu klein ist und zu viele Partitionen vorhanden sind GC überhaupt. Referenzen wurden ebenfalls gescannt. Daher wird in G1 Point-In verwendet, um das Problem zu lösen. Point-in bedeutet, welche Partitionen auf Objekte in der aktuellen Partition verweisen. Auf diese Weise werden ungültige Scans vermieden, indem diese Objekte nur als Roots gescannt werden. Müssen wir Bezüge zwischen neuen Generationen aufzeichnen, da es mehrere junge Generationen gibt? Dies ist unnötig, da bei jedem GC alle neuen Generationen gescannt werden, sodass nur Verweise von der alten Generation auf die neue Generation aufgezeichnet werden müssen.

Es ist zu beachten, dass bei vielen referenzierten Objekten der Zuweiser jede Referenz verarbeiten muss und der Zuweisungs-Overhead sehr groß ist. Um das Problem des Zuweisungs-Overheads zu lösen, wird ein weiteres eingeführt G1-Konzept, Kartentisch. Eine Kartentabelle unterteilt eine Partition logisch in kontinuierliche Bereiche fester Größe, und jeder Bereich wird als Karte bezeichnet. Karten sind normalerweise kleiner und liegen zwischen 128 und 512 Byte. Die Kartentabelle ist normalerweise ein Byte-Array, und die Raumadresse jeder Partition wird durch den Index der Karte (d. h. den Index des Arrays) identifiziert. Standardmäßig ist jede Karte nicht referenziert. Wenn auf einen Adressraum verwiesen wird, wird der diesem Adressraum entsprechende Wert des Array-Index als „0“ markiert, dh als schmutzig und referenziert. Darüber hinaus zeichnet RSet auch den Array-Index auf. Unter normalen Umständen ist dieses RSet tatsächlich eine Hash-Tabelle, der Schlüssel ist die Startadresse einer anderen Region, der Wert ist eine Menge und die darin enthaltenen Elemente sind der Index der Kartentabelle.

Young GC Phase:

  • Phase 1: Root Scan
    Statische und lokale Objekte werden gescannt

  • Phase 2 : RS aktualisieren
    Aktualisierung der Dirty-Card-Warteschlange RS verarbeiten

  • Phase 3: RS verarbeiten
    Objekte erkennen, die von der jungen Generation auf die alte Generation verweisen

  • Phase 4: Objektkopie
    Kopieren Sie das überlebende Objekt in den überlebenden/alten Bereich

  • Phase 5: Verarbeiten Sie die Referenzwarteschlange
    Weiche Referenz, schwache Referenz , virtuelle Referenzverarbeitung

4. G1 Mix GC

Mix GC führt nicht nur die normale Garbage Collection der neuen Generation durch, sondern recycelt auch einige Hintergrundscans Threads mit der Bezeichnung „Partition der alten Generation“.

Seine GC-Schritte sind in zwei Schritte unterteilt:

  1. Globale gleichzeitige Markierung (globale gleichzeitige Markierung)

  2. Kopieren Sie das Überleben Objekt (Evakuierung)

Vor der Durchführung von Mix GC wird zunächst die globale gleichzeitige Markierung durchgeführt. Was ist der Ausführungsprozess der globalen gleichzeitigen Markierung?

In G1 GC werden hauptsächlich Markierungsdienste für Mixed GC bereitgestellt und sind kein notwendiger Bestandteil eines GC-Prozesses. Der Ausführungsprozess der globalen gleichzeitigen Markierung ist in fünf Schritte unterteilt:

  • Anfangsmarkierung (STW)
    In dieser Phase markiert G1 GC die Wurzel. Diese Phase steht in engem Zusammenhang mit der regulären (STW) Müllabfuhr der jungen Generation.

  • Root-Region-Scan (Root-Region-Scan)
    G1 GC scannt Verweise auf die alte Generation im zunächst markierten Überlebensbereich und markiert die referenzierten Objekte. Diese Phase wird gleichzeitig mit der Anwendung (nicht STW) ausgeführt. Erst nach Abschluss dieser Phase kann mit der nächsten STW-Garbage Collection der jungen Generation begonnen werden.

  • Concurrent Marking
    G1 GC durchsucht den gesamten Heap nach zugänglichen (lebenden) Objekten. Diese Phase läuft gleichzeitig mit der Bewerbung und kann durch die STW-Garbage-Collection der jungen Generation unterbrochen werden

  • Endnote (Bemerkung, STW)
    Diese Phase ist die STW-Sammlung, die dabei hilft, den Markierungszyklus abzuschließen . G1 GC löscht den SATB-Puffer, verfolgt Live-Objekte, auf die nicht zugegriffen wurde, und führt die Referenzverarbeitung durch.

  • Bereinigung, STW)
    In dieser letzten Phase führt G1 GC STW-Operationen der Statistik und RSet-Reinigung durch. Während des Abrechnungszeitraums identifiziert G1 GC Bereiche, die völlig frei sind, und Bereiche, die für die gemischte Müllsammlung zur Verfügung stehen. Die Bereinigungsphase erfolgt teilweise gleichzeitig, da sie den leeren Bereich zurücksetzt und ihn in die freie Liste zurückführt.

Dreifarbmarkierungsalgorithmus

Wenn es um gleichzeitige Markierung geht, müssen wir den dreifarbigen Markierungsalgorithmus der gleichzeitigen Markierung verstehen. Dies ist eine nützliche Methode zur Beschreibung eines Tracing-Kollektors und kann verwendet werden, um die Korrektheit des Kollektors abzuleiten. Zunächst unterteilen wir Objekte in drei Typen.

  • Schwarz: Das Stammobjekt oder sowohl das Objekt als auch seine Unterobjekte werden gescannt.

  • Grau: Das Objekt selbst wird gescannt, aber noch nicht Nach dem Scannen der Unterobjekte im Objekt

  • Weiß: nicht gescannte Objekte Nach dem Scannen aller Objekte sind die endgültigen weißen Objekte unerreichbare Objekte, also Müllobjekte

Wenn der GC mit dem Scannen des Objekts beginnt, führen Sie die folgenden Schritte aus, um das Objekt zu scannen:

Das Stammobjekt wird auf Schwarz und das Unterobjekt auf Grau eingestellt.

Parsen des Java G1 Garbage Collectors

Fahren Sie mit dem Übergang von Grau fort und setzen Sie die Objekte, die Unterobjekte gescannt haben, auf Schwarz.

Parsen des Java G1 Garbage Collectors

Nachdem alle erreichbaren Objekte durchlaufen wurden, werden alle erreichbaren Objekte schwarz. Nicht erreichbare Objekte sind weiß und müssen aufgeräumt werden.

Parsen des Java G1 Garbage Collectors

Das sieht gut aus, aber wenn die Anwendung während des Markierungsprozesses ausgeführt wird, kann sich der Objektzeiger ändern. In diesem Fall werden wir auf ein Problem stoßen: Objektverlustproblem

Schauen wir uns die folgende Situation an, wenn der Garbage Collector die folgende Situation scannt:

Parsen des Java G1 Garbage Collectors

Zu diesem Zeitpunkt führte die Anwendung die folgenden Vorgänge aus:

A.c=C

B.c=null

Auf diese Weise wird das Zustandsdiagramm des Objekts wie folgt:

Parsen des Java G1 Garbage Collectors

Wenn der Garbage Collector den Scan zu diesem Zeitpunkt erneut markiert, sieht er so aus:

Parsen des Java G1 Garbage Collectors

Offensichtlich, Zu diesem Zeitpunkt gilt C als Weiß als Müll und muss bereinigt werden, was offensichtlich unvernünftig ist. Wie stellen wir also sicher, dass die von GC markierten Objekte nicht verloren gehen, wenn die Anwendung ausgeführt wird? Es gibt 2 Möglichkeiten:

  1. Objekt beim Einfügen aufzeichnen

  2. Objekt beim Löschen aufzeichnen

Dies entspricht den beiden unterschiedlichen Implementierungsmethoden von CMS und G1:

In CMS wird die inkrementelle Aktualisierung verwendet, solange sie in der Schreibbarriere gefunden wird, wenn eine Referenz auf ein weißes Objekt zugewiesen wird ein Feld eines schwarzen Objekts, dann wird das weiße Objekt grau. Das heißt, es wird beim Einfügen aufgezeichnet.

In G1 wird die STAB-Methode (Snapshot-at-the-Beginn) verwendet, um alle Objekte beim Löschen aufzuzeichnen. Sie besteht aus 3 Schritten:

1, am Anfang Beim Markieren, a Es wird ein Snapshot-Diagramm erstellt, um die überlebenden Objekte zu markieren

2. Während der gleichzeitigen Markierung werden alle geänderten Objekte in die Warteschlange gestellt (in der Schreibbarriere werden alle Objekte, auf die alte Referenzen verweisen, nicht weiß)

3, möglicherweise gibt es freien Müll, der beim nächsten Mal gesammelt wird

Auf diese Weise kann G1 jetzt wissen, welche alten Partitionen den meisten Müll recyceln können. Wenn die globale gleichzeitige Markierung abgeschlossen ist, wird zu einem bestimmten Zeitpunkt Mix GC gestartet. Diese Garbage Collections werden als „Hybrid“ bezeichnet, da sie nicht nur die normale Garbage Collection der jungen Generation durchführen, sondern auch einige vom Hintergrund-Scan-Thread markierte Partitionen sammeln. Die gemischte Speicherbereinigung ist wie folgt:

Parsen des Java G1 Garbage Collectors

Hybrid GC verwendet auch eine Kopierbereinigungsstrategie. Wenn der GC abgeschlossen ist, wird der Speicherplatz wieder freigegeben.

Parsen des Java G1 Garbage Collectors

An diesem Punkt ist die Hybrid-GC zu Ende. Im nächsten Abschnitt befassen wir uns mit der Tuning-Praxis.

5. Tuning-Praxis

MaxGCPauseMillis-Tuning

Die grundlegendsten Parameter für die Verwendung von GC wurden bereits früher eingeführt:

- XX: +UseG1GC -Xmx32g -XX:MaxGCPauseMillis=200

Die ersten beiden Parameter sind leicht zu verstehen. Wie konfiguriere ich den letzteren MaxGCPauseMillis-Parameter? Dieser Parameter bedeutet wörtlich die maximal zulässige Pausenzeit für GC. G1 versucht sicherzustellen, dass die Zeit jeder GC-Pause innerhalb des festgelegten MaxGCPauseMillis-Bereichs liegt. Wie erreicht G1 also die maximale Pausenzeit? Dies beinhaltet ein anderes Konzept, CSet (Collection Set). Damit ist die Menge der Bereiche gemeint, die in einem Garbage Collector gesammelt werden.

  • Junger GC: Wählen Sie alle Regionen in der neuen Generation aus. Kontrollieren Sie die Kosten junger GC, indem Sie die Anzahl der Regionen in der neuen Generation kontrollieren.

  • Gemischte GC: Wählen Sie alle Regionen der neuen Generation sowie mehrere Regionen der alten Generation mit hohen Sammeleinnahmen basierend auf globalen Statistiken zur gleichzeitigen Markierung aus. Wählen Sie die Region der alten Generation mit hohem Umsatz so weit wie möglich innerhalb des vom Benutzer festgelegten Kostenziels aus.

Nachdem wir dies verstanden haben, wird es für uns einfacher sein, die maximale Pausenzeit festzulegen. Erstens gibt es eine Grenze für die maximale Pausenzeit, die wir tolerieren können, und wir müssen sie innerhalb dieser Grenze festlegen. Doch welcher Wert sollte eingestellt werden? Wir müssen ein Gleichgewicht zwischen Durchsatz und MaxGCPauseMillis herstellen. Wenn „MaxGCPauseMillis“ zu klein eingestellt ist, kommt es zu häufigen GCs und der Durchsatz nimmt ab. Wenn MaxGCPauseMillis zu groß eingestellt ist, wird die Anwendungspausenzeit länger. Die Standardpausenzeit von G1 beträgt 200 Millisekunden. Wir können von hier aus beginnen und die entsprechende Zeit anpassen.

Andere Tuning-Parameter

-XX:G1HeapRegionSize=n

Die Größe des G1-Regionssatzes. Die Werte sind Zweierpotenzen und reichen von 1 MB bis 32 MB. Das Ziel besteht darin, basierend auf der minimalen Java-Heap-Größe etwa 2048 Regionen herauszuarbeiten.

-XX:ParallelGCThreads=n

Legen Sie den Wert der Anzahl der STW-Worker-Threads fest. Legen Sie den Wert von n auf die Anzahl der logischen Prozessoren fest. Der Wert von n entspricht der Anzahl der logischen Prozessoren, bis zu einem Maximum von 8.

Wenn mehr als acht logische Prozessoren vorhanden sind, legen Sie den Wert von n auf etwa 5/8 der Anzahl der logischen Prozessoren fest. Dies funktioniert in den meisten Fällen, außer bei größeren SPARC-Systemen, wo der Wert von n etwa 5/16 der Anzahl der logischen Prozessoren betragen kann.

-XX:ConcGCThreads=n

Legen Sie die Anzahl der parallel markierten Threads fest. Legen Sie n auf ungefähr 1/4 der Anzahl paralleler Garbage-Collection-Threads (ParallelGCThreads) fest.

-XX:InitiatingHeapOccupancyPercent=45

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

Vermeiden Sie die Verwendung der folgenden Parameter:

Vermeiden Sie die explizite Festlegung der Größe der jungen Generation mit der Option -Xmn oder anderen verwandten Optionen wie -XX:NewRatio. Problem behoben, bei dem die Größe der jungen Generation die Pausenzeitziele überschreibt.

Vollständige GC auslösen

In einigen Fällen löst G1 eine vollständige GC aus. Zu diesem Zeitpunkt degeneriert G1 und verwendet den seriellen Kollektor, um die Müllbereinigungsarbeit abzuschließen Vervollständigen Sie den Vorgang. GC funktioniert und die GC-Pausenzeit erreicht die zweite Stufe. Die gesamte Anwendung befindet sich in einem angehaltenen Animationszustand und kann keine Anfragen verarbeiten. Unser Programm möchte dies natürlich nicht sehen. In welchen Situationen kommt es also zu einer vollständigen GC?

  • Fehler im gleichzeitigen Modus

G1 startet den Markierungszyklus, aber die alte Generation ist vor Mix GC gefüllt, und G1 wird dabei aufgeben Zeitmarkierungszyklus. In diesem Fall müssen Sie die Heap-Größe erhöhen oder den Zyklus anpassen (z. B. die Anzahl der Threads erhöhen -XX:ConcGCThreads usw.).

  • Hochstufung fehlgeschlagen oder Evakuierung fehlgeschlagen

G1 verfügt nicht über genügend Speicher für überlebende Objekte oder hochgestufte Objekte bei der Durchführung der GC, was eine vollständige GC auslöst. Sie können im Protokoll sehen, ob der Speicherplatz erschöpft ist oder der Speicherplatz überschritten ist. Der Weg, dieses Problem zu lösen, ist:

a, Erhöhen Sie den Wert der Option -XX:G1ReservePercent (und erhöhen Sie die Gesamtheap-Größe entsprechend), um die Menge des reservierten Speichers für den „Zielraum“ zu erhöhen.

b, Starten Sie den Markierungszyklus frühzeitig, indem Sie -XX:InitiatingHeapOccupancyPercent reduzieren.

c, Sie können die Anzahl der parallelen Markierungsthreads auch erhöhen, indem Sie den Wert der Option -XX:ConcGCThreads erhöhen.

  • Riesenobjektzuweisung fehlgeschlagen

Wenn ein Riesenobjekt keinen geeigneten Platz für die Zuweisung findet, wird die vollständige GC gestartet, um den Platz freizugeben. In diesem Fall sollten Sie die Zuweisung einer großen Anzahl riesiger Objekte vermeiden, den Speicher erhöhen oder -XX:G1HeapRegionSize erhöhen, damit das riesige Objekt kein riesiges Objekt mehr ist.

Aufgrund des begrenzten Platzes gibt es viele Tuning-Übungen für G1, daher werde ich sie hier nicht einzeln auflisten. Sie können sie in Ihrer täglichen Praxis langsam erkunden. Abschließend freue ich mich auf die offizielle Veröffentlichung von Java 9. Wird sich die Leistung von Java, das standardmäßig G1 als Garbage Collector verwendet, noch einmal verbessern?


Das obige ist der detaillierte Inhalt vonParsen des Java G1 Garbage Collectors. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn