Ausführliche Erklärung des G1 Garbage Collectors

1. Entwicklungshintergrund des G1 Garbage Collectors

1.1 Mängel des CMS Garbage Collectors

Siehe Garbage Collector von JVM

JVM团队设计出G1收集器的目的就是为了取代CMS收集器**(老年代-标记清除算法)**,因为CMS收集器在很多场景下存在诸多问题, werden die Mängel wie folgt vollständig freigelegt:

  • CMS收集器对CPU资源非常敏感. In der Parallelitätsstufe wird der Benutzer-Thread zwar nicht angehalten, aber CPU-Ressourcen belegt und das Referenzprogramm verlangsamt und der Gesamtdurchsatz verringert. Die Anzahl der von CMS gestarteten Recycling-Threads beträgt standardmäßig:(Anzahl CPUs+3) / 4
  • CMS收集器无法处理浮动垃圾, da der Benutzer-Thread während der gleichzeitigen Reinigungsphase von CMS noch läuft, wird natürlich während des Programmablaufs ständig neuer Müll erzeugt. Dieser Teil des Mülls erscheint nach dem Markierungsprozess, genannt "Floating Garbage", und kann von CMS nicht verarbeitet werden Sie in dieser Sammlung mussten auf die nächste GC warten, um sie zu bereinigen.
  • 并发失败(Concurrent Mode Failure)问题, aufgrund des „schwimmenden Mülls“, der während der Garbage-Collection-Phase entsteht ,Daher kann der CMS-Kollektor nicht wie andere Kollektoren warten, bis die alte Generation fast vollständig gefüllt ist, und muss beim gleichzeitigen Sammeln einen Teil des Speicherplatzes für den Programmbetrieb reservieren.. Standardmäßig wird der CMS-Kollektor aktiviert, wenn im Alter **68%** Speicherplatz verwendet wird, und der Auslöseprozentsatz kann auch um den Wert des Parameters -XX:CMSInitiatingOccupancyFraction erhöht werden, um die Anzahl der Speicherwiederverwendungen zu reduzieren und Leistung verbessern. Wenn der während der Ausführung des CMS reservierte Speicher die Anforderungen anderer Threads des Programms nicht erfüllen kann, tritt ein „Concurrent Mode Failure" -Fehler auf. Zu diesem Zeitpunkt startet die virtuelle Maschine einen Backup-Plan: Aktivieren Sie vorübergehend den Serial Old Collector den Müll im Alter wieder einzusammeln, so dass die Pausenzeit sehr lang ist. Wenn der Parameter -XX:CMSInitiatingOccupancyFraction zu hoch eingestellt ist, führt dies daher leicht dazu, dass "Concurrent Mode Failure" fehlschlägt und stattdessen die Leistung abnimmt.
  • CMS是基于“标记-清除”算法实现的收集器,会产生大量不连续的内存碎片. Wenn in der alten Generation zu viele Raumfragmente vorhanden sind und Sie keinen ausreichend großen zusammenhängenden Speicher zum Speichern von Objekten finden können, müssen Sie im Voraus eine vollständige GC auslösen. Um dieses Problem zu lösen, stellt der CMS-Kollektor einen Switch-Parameter -XX:UseCMSCompactAtFullCollection bereit, der verwendet wird, um einen Defragmentierungsprozess nach der vollständigen GC hinzuzufügen. Sie können auch den Parameter -XX:CMSFullGCBeforeCompaction verwenden, um festzulegen, wie oft die ausgeführt werden soll nicht komprimiertes Full GC, gefolgt von Let's do a defragmentation process.

1.2 Funktionen des G1 Garbage Collectors

Der G1-Kollektor (Garbage First) ist ein neuer Kollektor, der von JDK7 bereitgestellt wird. JDK9Er wird als offizieller Standard-GC-Kollektor in bezeichnet. Im Vergleich zum CMS-Kollektor ist die auffälligste Verbesserung

  • Basierend auf "标记-整理"dem Algorithmus wird es nach der Sammlung keine Speicherfragmentierung geben
  • Pausenzeiten können sehr genau gesteuert werden, was eine pausenarme Garbage Collection ohne Durchsatzeinbußen ermöglicht.

2. Das Speichermodell des G1 Garbage Collectors

Der G1-Kollektor übernimmt nicht das traditionelle physische Isolationslayout der neuen Generation und der alten Generation, sondern teilt nur logisch die neue Generation und die alte Generation und teilt den gesamten Heap-Raum in 2048 unabhängige Speicherblockregionen gleicher Größe ist ein logisches A kontinuierliches Stück Speicher, die spezifische Größe hängt von der tatsächlichen Größe des Heaps ab, die Gesamtsteuerung liegt zwischen 1M - 32M und es ist die N-te Potenz von 2 (1M, 2M, 4M, 8M, 16M und 32M ).

G1收集器通过跟踪Region中的垃圾堆积情况,每次根据设置的垃圾回收时间,回收优先级最高的区域,避免整个新生代或整个老年代的垃圾回收,使得stop the world的时间更短、更可控,同时在有限的时间内可以获得最高的回收效率​。

​Durch die Bereichsaufteilung und den Recyclingmechanismus für vorrangige Bereiche wird sichergestellt, dass der G1-Kollektor in begrenzter Zeit die höchste Garbage Collection-Effizienz erzielen kann.

2.1 Partitionsbereich

Bildbeschreibung hier einfügen

Der G1 Garbage Collector unterteilt den Heap-Speicher in mehrere Regionen, und jede Regionspartition kann nur eine Rolle spielen, entweder den Eden-Bereich, den S-Bereich oder den Bereich der alten Generation O, und der leere Bereich stellt nicht zugeordneten Speicher dar. Es gibt einen speziellen Bereich H区(Humongous)gewidmet der Aufbewahrung riesiger Objekte,Wenn die Größe eines Objekts 50 % der Kapazität der Region überschreitet, betrachtet G1 es als riesiges Objekt

In anderen Garbage Collectors werden diese Riesenobjekte standardmäßig im Alter zugewiesen, aber wenn es sich um ein kurzlebiges Riesenobjekt handelt, wirkt sich das Versetzen in das Alter negativ auf den Garbage Collector aus und löst häufige GC im Alter aus Alter. Um dieses Problem zu lösen, teilt G1 einen H-Bereich, um riesige Objekte zu speichern. Wenn ein H-Bereich kein riesiges Objekt aufnehmen kann, sucht G1 nach einem zusammenhängenden H-Bereich, um es zu speichern. Wenn es keinen zusammenhängenden H-Bereich finden kann, wird es muss Full GC starten.

2.2Erinnere dich an Set

Sowohl bei seriellen als auch bei parallelen Kollektoren scannt GC den gesamten Heap, um festzustellen, ob sich ein Objekt auf einem erreichbaren Pfad befindet . Um jedoch Full-Heap-Scans im STW-Stil zu vermeiden, weist G1 jeder Region (Region) einen zu RSet(Remembered Set), der intern einem Rückwärtszeiger ähnelt und die Verweise anderer Regionen auf die aktuelle Region aufzeichnet, was einen enormen Vorteil bringt: When Wenn Sie eine Region zurückfordern, müssen Sie keinen vollständigen Heap-Scan durchführen, Sie müssen nur ihr RSet scannen, um externe Referenzen zu finden, um festzustellen, ob die referenzierten Objekte in dieser Partition aktiv sind, und dann das Überleben von Objekten in dieser Partition zu bestimmen. Diese Referenzen sind eine der Wurzeln der Anfangsmarke .

Tatsächlich müssen nicht alle Referenzen in RSet aufgezeichnet werden. Wenn die Referenzquelle das Objekt dieser Partition ist, muss sie nicht in RSet aufgezeichnet werden; gleichzeitig muss jedes Mal, wenn G1 GC, die gesamte neue Generation aufgezeichnet werden gescannt, so dass der Bezug Die Quelle ist ein Objekt der jungen Generation und muss nicht in RSet erfasst werden, also muss am Ende nur der Bezug zwischen der alten Generation und der neuen Generation erfasst werden.

2.3Kartentisch

Wenn ein Thread die Referenz innerhalb der Region ändert, muss er RSet benachrichtigen, um die Datensätze darin zu ändern. Es sollte beachtet werden, dass der Setter bei vielen referenzierten Objekten jede Referenz verarbeiten muss und der Setter-Overhead sehr hoch sein wird, sodass der G1-Sammler Card Table einführt, um dieses Problem zu lösen.

Eine Kartentabelle unterteilt eine Region logisch in mehrere fortlaufende Bereiche fester Größe (zwischen 128 und 512 Byte), und jeder Bereich wird als Kartenkarte bezeichnet, sodass Karte die kleinste verfügbare Granularität im Heap-Speicher ist. Das zugewiesene Objekt belegt eine Nummer von physisch zusammenhängenden Karten.Wenn Sie nach Verweisen auf Objekte in der Partition suchen, kann die Karte Card durchsucht werden (siehe RSet).Jedes Mal, wenn der Speicher wiederhergestellt wird, ist es auch eine Karte für die angegebene Partition. Jede Karte verwendet ein Byte, um aufzuzeichnen, ob sie modifiziert wurde, und die Kartentabelle ist eine Sammlung dieser Bytes, die ein Byte-Array ist, und die Raumadresse jeder Partition wird durch den Index des Karten-Arrays identifiziert. Standardmäßig wird nicht auf jede Karte verwiesen. Wenn auf einen Adressraum verwiesen wird, wird der Wert des Array-Index, der diesem Adressraum entspricht, als "0" markiert, d. h. er wird als schmutzig markiert und referenziert. Außerdem wird RSet dies tun Laden Sie auch dieses Array herunter Markieren Sie es.

Eine Region kann mehrere Threads haben, die gleichzeitig modifiziert werden, also kann RSet auch gleichzeitig modifiziert werden. Um Konflikte zu vermeiden, teilt der G1-Garbage Collector das RSet weiter in mehrere HashTables auf, und jeder Thread ändert seine eigene HashTable. Letztendlich ist ein RSet logischerweise eine Sammlung dieser HashTables. Die Hash-Tabelle stellt eine gängige Methode zur Implementierung von RSet dar. Ihr Vorteil besteht darin, dass Duplikate entfernt werden können, was bedeutet, dass die Größe von RS der Anzahl der geänderten Zeiger entspricht. Im Falle keiner Duplizierung entspricht die Anzahl der RS- und Schreiboperationen Die Zahl ist gleichwertig.

HashTable 的 Key 是别的 Region 的起始地址,Value是一个集合,里面的元素是Card Table的Index
Bildbeschreibung hier einfügen

Die gepunktete Linie von RS in der Abbildung zeigt, dass RSet keine separate und unterschiedliche Datenstruktur von Card Table ist, sondern dass RS ein konzeptionelles Modell ist. Tatsächlich ist Card Table eine Implementierung von RS.

G1 verwendet den Speicher in Einheiten von Regionen, während die Zuordnung von Objekten in Einheiten von Karten erfolgt

2.4 Schreibbarriere von RSet

Schreibsperre bedeutet, dass jedes Mal, wenn ein Referenzreferenztyp eine Schreiboperation ausführt, eine Schreibsperre mit Schreibsperre generiert wird, um die Operation vorübergehend zu unterbrechen und einige zusätzliche Aktionen auszuführen.

Bei Schreibbarrieren ist es sehr wichtig, unnötige Schreiboperationen herauszufiltern, da der Befehlsaufwand für das Schreiben von Barrieren sehr teuer ist, was nicht nur die Geschwindigkeit des Setters erhöhen, sondern auch die Belastung des Collectors verringern kann. Die Schreibbarriere des G1-Kollektors ist komplementär zum RSet. Wenn eine Schreibbarriere generiert wird, prüft sie, ob das Objekt, auf das die zu schreibende Referenz zeigt, sich in einer anderen Region befindet als die Daten des Referenztyps. Wenn sie unterschiedlich sind, Die relevanten Referenzinformationen werden in der Referenz über CardTable aufgezeichnet. In dem RSet, das der Region entspricht, in der sich das zeigende Objekt befindet, kann das RSet durch Filtern stark reduziert werden.

(1) Zaun vor dem Schreiben: Wenn eine Zuweisungsanweisung ausgeführt werden soll, ändert das Objekt auf der linken Seite der Gleichung die Referenz auf ein anderes Objekt, dann die Partition, auf der das Objekt ursprünglich durch das Objekt auf der linken Seite referenziert wurde die Gleichung verliert eine Referenz, und die JVM muss in der sein. Bevor die Zuweisungsanweisung wirksam wird, wird das Objekt, das die Referenz verloren hat, aufgezeichnet. Aber die JVM verwaltet das RSet nicht sofort, aber durch Stapelverarbeitung wird das RSet in Zukunft aktualisiert

(2) Post-Write Fence: Wenn eine Zuweisungsanweisung ausgeführt wird, erhält das Objekt auf der rechten Seite der Gleichung einen Verweis auf das Objekt auf der linken Seite und das RSet der Partition, in der sich das Objekt auf der rechten Seite befindet Gleichung befindet, sollte ebenfalls aktualisiert werden. Um den Overhead zu reduzieren, wird RSet nach Auftreten des Post-Write Fence nicht sofort aktualisiert, sondern zeichnet auch nur das Aktualisierungsprotokoll für die Stapelverarbeitung in der Zukunft auf

​ Wenn der G1-Garbage Collector die Garbage Collection durchführt, kann das Hinzufügen von RSet zum Aufzählungsbereich des GC-Root-Knotens sicherstellen, dass kein globales Scannen durchgeführt wird und es keine Auslassungen gibt. Darüber hinaus haben die übrigen von der JVM verwendeten generationsbezogenen Garbage Collectors ebenfalls Schreibbarrieren.Beispielsweise wird jedes Mal, wenn ein Verweis auf ein Objekt in der alten Generation geändert wird, um auf ein Objekt in der jungen Generation zu verweisen, erfasst und Wenn Sie die alte Generation sammeln, können Sie vermeiden, die gesamte alte Generation zu scannen, um die Wurzel zu finden.

Die Schreibbarriere des Garbage Collectors von G1

  • globaler Satz gefüllter Puffer: ein globaler Satz, der von allen Threads gemeinsam genutzt wird und die Sammlung gefüllter Protokollpuffer speichert
  • Thread-Protokollpuffer: der eigene Protokollpuffer jedes Threads. Alle Threads legen den Schreibsperrdatensatz zuerst in ihren eigenen Protokollpuffer, und wenn dieser voll ist, legen sie den Protokollpuffer in den globalen Satz gefüllter Puffer und beantragen dann einen Protokollpuffer;

2.5 Set sammeln

Collect Set(CSet)是指,在 Evacuation 阶段,由G1垃圾回收器选择的待回收的Region集合, werden in jedem Collector alle Partitionen von CSet freigegeben und die internen überlebenden Objekte werden auf die zugewiesenen freien Partitionen übertragen . Die weiche Echtzeitleistung von G1 wird durch die Auswahl von CSet realisiert. Entsprechend den zwei Modi des Algorithmus, dem vollständig jungen Generationsmodus und dem teilweise jungen Modus, kann die Auswahl von CSet in zwei Typen unterteilt werden:

  1. Völlig junger Generationsmodus: Auch bekannt als junger GC, in diesem Modus enthält der CSet nur junge Regionen, und G1 entspricht dem weichen Echtzeitziel, indem die Anzahl der Regionen in der neuen Generation angepasst wird;
  2. Teilweise junger Modus: Dieser Modus wird auch als Mixed GC bezeichnet und wählt alle jungen Regionen und einen Teil der alten Region aus. Die Auswahl der alten Region basiert auf der Anzahl der überlebenden Objekte in der Phase des Markierungszyklus und Herausfiltern der Partition mit dem höchsten Recycling-Einkommen Add to CSet (die Region mit den wenigsten überlebenden Objekten wird recycelt)

CSet-Zugriffsbedingungen für Kandidatenpartitionen der alten Generation können durch den Aktivitätsschwellenwert -XX:G1MixedGCLiveThresholdPercent (Standard 85%) festgelegt werden , um diese Objekte mit enormen Wiederherstellungskosten abzufangen; gleichzeitig kann jede gemischte Sammlung Kandidaten der alten Generation enthalten Partitionen, Die Obergrenze der Anzahl kann entsprechend dem Anteil von CSet an der Gesamtgröße des Heaps festgelegt werden -XX:G1OldCSetRegionThresholdPercent (Standard 10%).

Aus dem Obigen ist ersichtlich, dass die Sammlung von G1 auf der Funktionsweise von CSet basiert. Es gibt keinen offensichtlichen Unterschied zwischen der Sammlung der jungen Generation und der gemischten Sammlung. Der größte Unterschied liegt in den Auslösebedingungen der beiden Sammlungen .

3.G1-Garbage-Collection-Prozess

Überblick über den Gesamtprozess

G1 bietet zwei GC-Modi, Young GCund Mixed GCbeide sind Stop The World (STW) , aber bevor wir über Garbage Collection sprechen, lassen Sie uns die Objektzuweisungsstrategie von G1 vorstellen.

3.1 Objektzuordnungsstrategie

Jede zugewiesene Region kann in zwei Teile unterteilt werden, zugewiesene und nicht zugewiesene, und die Grenze zwischen ihnen wird oben genannt. Um ein Objekt einer Region zuzuweisen, müssen Sie im Allgemeinen nur den Wert von top erhöhen. Der Ablauf ist wie folgt:

Bildbeschreibung hier einfügen

(1) Lokaler Zuweisungspuffer des Threads Lokaler Zuweisungspuffer des Threads (TLab):

Wenn Objekte in einem gemeinsam genutzten Bereich zugewiesen werden, müssen wir einen Synchronisierungsmechanismus verwenden, um Parallelitätskonflikte zu lösen. Um die durch Parallelitätskonflikte verlorene Synchronisierungszeit zu reduzieren, weist G1 jedem Anwendungsthread und GC-Thread When TLAB einen lokalen Zuweisungspuffer zu Objektspeicher zuweist, wird er in diesem Puffer zugewiesen, und es besteht keine Notwendigkeit für eine Synchronisierung zwischen Threads, was die GC-Effizienz verbessert. Aber wenn ein Thread seinen eigenen Puffer erschöpft, muss er einen neuen Puffer beantragen. Zu diesem Zeitpunkt wird es noch Parallelitätsprobleme geben. Der G1-Kollektor verwendet die CAS-Operation (Compare And Swap).

Offensichtlich bringt die Verwendung der TLAB-Technologie Fragmente mit sich. Wenn beispielsweise ein Thread in seinem eigenen Buffer allokiert, obwohl noch Platz im Buffer vorhanden ist, das zugewiesene Objekt zu groß ist, um den freien Speicherplatz aufzunehmen, kann der Thread zu diesem Zeitpunkt nur einen neuen Buffer beantragen. und der freie Speicherplatz im ursprünglichen Puffer wird verschwendet. Sowohl die Größe des Puffers als auch die Anzahl der Threads wirken sich auf die Anzahl dieser Fragmente aus.

​ Während jeder Garbage Collection kann jeder GC-Thread auch exklusiv einen lokalen Puffer (GCLAB) belegen, um Objekte zu übertragen und überlebende Objekte in den Survivor-Space oder den Old-Generation-Space zu kopieren;

​ Für Objekte, die vom Eden/Survivor Space zum Survivor/Old Generation Space hochgestuft werden, gibt es auch einen GC-exklusiven lokalen Puffer für Operationen. Dieser Teil wird Promotion Local Buffer (PLAB) genannt.

(2) Zuordnung im Bereich Eden:

Für Objekte, die nicht im TLAB-Bereich zugewiesen werden können, versucht die JVM, sie im Eden-Bereich zuzuordnen. Wenn der Eden-Raum das Objekt nicht aufnehmen kann, kann der Raum nur in der alten Generation zugewiesen werden.

(3) Riesige Flächenaufteilung:

​ Riesige Objekte belegen ausschließlich eine oder mehrere fortlaufende Partitionen, wobei die erste Partition als Starts Humongous markiert ist und benachbarte fortlaufende Partitionen als Continues Humongous markiert sind. Da Sie die Optimierung von TLab nicht genießen können und den gesamten Heap scannen müssen, um einen zusammenhängenden Speicherplatz zu bestimmen, ist der Aufwand für die Bestimmung der Startposition von riesigen Objekten sehr hoch.Wenn möglich, sollte die Anwendung vermeiden, dass riesige Objekte generiert werden Objekte.

G1 hat eine interne Optimierung vorgenommen: Stellt sich heraus, dass kein Hinweis auf das Riesenobjekt vorhanden ist, kann es direkt in den Sammelkreislauf der jungen Generation zurückgeführt werden.

3.2G1 Junge GC

Wenn das Eden-Gebiet voll ist und die JVM dem Eden-Gebiet keine Objekte zuordnen kann, wird eine Young-Generation-Collection-Young-GC im STW-Stil ausgelöst, und die überlebenden Objekte im Eden-Gebiet werden in das to survivor-Gebiet kopiert; die überlebenden Objekte im Von-Survivor-Bereich werden gemäß den Schwellenwerten für die Anzahl der Überlebenszeiten in PLAB, in den Survivor-Bereich bzw. in die alte Generation kopiert; wenn der Survivor-Bereich nicht ausreicht, werden einige Daten im Eden-Bereich direkt kopiert in den Bereich der alten Generation befördert. Am Ende sind die Daten im Eden-Raum leer, der GC funktioniert nicht mehr und der Anwendungs-Thread wird weiter ausgeführt.

Der junge GC ist auch dafür verantwortlich, das Alter (Überlebenszeiten) des Objekts aufrechtzuerhalten und bei der Beurteilung des Verbleibs des alternden (dauernden) Objekts zu helfen, wenn es befördert wird. Der junge GC behält zuerst die Summe der Beförderungsobjektgröße und Altersinformationen in der Alterstabelle bei und füllt dann die Kapazität gemäß der Alterstabelle, Überlebendengröße und Überlebenden -XX:TargetSurvivorRatio (Standard 50 %), maximaler Beschäftigungsschwellenwert - XX:MaxTenuringThreshold (Standard 15), Berechnen Sie einen angemessenen Tenure-Schwellenwert, und alle Objekte, die den Tenure-Schwellenwert überschreiten, werden in die alte Generation hochgestuft.

​ Zu diesem Zeitpunkt müssen wir uns mit der Frage befassen, wie finden wir alle Root-Objekte, wenn nur GC-Objekte der neuen Generation vorhanden sind? Sind alle Objekte in der alten Generation verwurzelt? Es wird viel Zeit in Anspruch nehmen, auf diese Weise zu scannen. Wir müssen also das oben eingeführte RSet verwenden, das die Verweise anderer Regionen auf die aktuelle Region aufzeichnet.Daher muss bei der Durchführung von Young GC beim Scannen der Wurzel nur diese Region gescannt werden, anstatt die gesamte Region. alt Alter.

3.2.1 Der detaillierte Recyclingprozess von jungen GC:

(1) Die erste Stufe, Root-Scanning:

Die Wurzel bezieht sich auf das Objekt, auf das die statische Variable zeigt, die lokale Variable in der ausgeführten Methodenaufrufkette und so weiter. Die Root-Referenz dient zusammen mit den vom RSet aufgezeichneten externen Referenzen als Einstiegspunkt für das Scannen von Live-Objekten.

(2) Aktualisieren Sie im zweiten Schritt RSet:

Verarbeite die Karten in der Dirty-Card-Warteschlange und aktualisiere das RSet.Nach Abschluss dieser Phase kann das RSet die Verweise der alten Generation auf dieObjekte in der Bereichspartition, in der es sich befindet, genau widerspiegeln

(3) Die dritte Stufe: Verarbeitung von RSet:

Identifizieren Sie die Objekte in Eden, auf die von den Objekten der alten Generation gezeigt wird, und diese Objekte in Eden, auf die gezeigt wird, werden als überlebende Objekte betrachtet

(4) Die vierte Stufe: Objekt kopieren:

Die überlebenden Objekte im Eden-Bereich werden in den Zu-Überlebenden-Bereich kopiert; die überlebenden Objekte im Von-Überlebenden-Bereich werden in den PLAB-zum-Überlebenden-Bereich befördert und altern entsprechend der Überlebenszeitschwelle; wenn der Überlebende-Bereich ist Nicht genug, einige Daten im Eden-Bereich werden direkt in den Bereich der alten Generation hochgestuft.

(5) Die fünfte Stufe: Verarbeitungshinweise:

Beim Umgang mit weichen Referenzen, schwachen Referenzen und Phantomreferenzen werden die Daten im Eden-Raum schließlich leer sein und der GC wird aufhören zu arbeiten, während die Objekte im Zielspeicher kontinuierlich ohne Fragmentierung gespeichert werden, sodass der Kopiervorgang erfolgreich sein kann die Wirkung der Speicherorganisation und reduzieren die Fragmentierung.

3.3G1 Gemischte GC

Nachdem die junge Generation weiterhin Müllsammelaktivitäten durchführt, um zu verhindern, dass der Raum der alten Generation erschöpft wird. Wenn der von der alten Generation belegte Speicherplatz den gesamten Heap-Verhältnis-IHOP-Schwellenwert -XX:InitiatingHeapOccupancyPercent (Standard 45%) überschreitet, startet G1 eine gemischte Garbage Collection Mixed GC.Mixed GC führt nicht nur eine normale Garbage Collection der neuen Generation durch, sondern recycelt auch einige Hintergrundscans Durch Threads gekennzeichnete Partition der alten Generation. Der Mixed-GC-Schritt ist hauptsächlich in zwei Schritte unterteilt:

(1) Global Concurrent Marking (Global Concurrent Marking)

(2) Überlebende Objekte kopieren (Evakuierung)

Was hier besonders beachtet werden muss, ist, dass Mixed GC nicht Full GC ist, sondern nur, wenn Mixed GC zu spät ist, um die alte Region zurückzugewinnen, dh wenn Objekte in der alten Generation zugewiesen werden müssen, aber festgestellt wird, dass es nicht genug gibt Leerzeichen, wird zu diesem Zeitpunkt eine vollständige GC ausgelöst

3.3.1 Globale gleichzeitige Markierung

​ Vor dem gemischten Recycling wird zuerst eine globale gleichzeitige Markierung durchgeführt.In G1 GC ist es kein notwendiger Teil eines GC-Prozesses, sondern bietet hauptsächlich Markierungsdienste für gemischte GC. Der Ausführungsprozess der globalen gleichzeitigen Markierung ist in fünf Schritte unterteilt:

(1) Anfangszeichen (Anfangszeichen, STW):

Alle GC-Roots-Knoten und direkt erreichbare Objekte werden markiert.Diese Stufe muss die Welt anhalten, dauert aber eine kurze Zeit.

Der anfängliche Markierungsprozess ist eng mit dem jungen GC verbunden. Wenn der IHOP-Schwellenwert erreicht ist, initiiert G1 tatsächlich nicht sofort einen gleichzeitigen Markierungszyklus, sondern wartet auf die nächste Sammlung der jungen Generation und verwendet die STW-Periode der Sammlung der jungen Generation, um die anfängliche Markierung abzuschließen.Diese Methode wird Ausleihen genannt .

(2) Root-Region-Scan (Root-Region-Scan):

Scannen Sie die erreichbaren Objekte des Gebiets der alten Generation im anfänglich markierten Überlebensgebiet (Überlebensgebiet) und markieren Sie das Wurzelobjekt. Diese Phase läuft gleichzeitig mit der Bewerbung, und der junge GC des nächsten STW kann erst beginnen, wenn diese Phase abgeschlossen ist.

Da RSet keine Verweise aus der jungen Region aufzeichnet, kann es vorkommen, dass ein überlebendes Objekt in der alten Generation nur von Objekten in der jungen Generation referenziert wird. In einem jungen GC werden diese überlebenden Objekte der jungen Generation in die Survivor-Region kopiert, sodass diese Survivor-Regionen gescannt werden müssen, um Verweise auf diese Objekte zu finden, die auf die alte Generation verweisen, als Teil der gleichzeitigen Markierungsphase, in der die Wurzel der gescannt wird Alte Generation.

(3) Gleichzeitige Markierung:

Führen Sie eine Erreichbarkeitsanalyse für Objekte im Heap von GC Roots durch, um überlebende Objekte zu finden. Dieser Prozess kann durch junge GC unterbrochen werden, und neue Referenzen (oder Referenzaktualisierungen), die während der gleichzeitigen Markierungsphase generiert werden, werden gleichzeitig von der Schreibsperre von SATB aufgezeichnet , wird der gleichzeitige Markierungs-Thread auch periodisch die Datensätze der globalen STAB-Pufferliste prüfen und verarbeiten und die Objektreferenzinformationen aktualisieren. Wenn sich während dieser Phase herausstellt, dass alle Objekte in der Region Müll sind, wird die Region sofort zurückgefordert. Gleichzeitig wird während des gleichzeitigen Markierungsprozesses das Überlebensverhältnis von Objekten in jeder Region berechnet.

In der gleichzeitigen Markierungsphase müssen wir den Dreifarben-Markierungsalgorithmus verstehen, den wir im Folgenden vorstellen werden

(4) Bemerkung (Bemerkung, STW):

Die Neumarkierungsphase dient dazu, den Teil des Markierungsdatensatzes zu korrigieren, der sich aufgrund des fortgesetzten Betriebs der Anwendung während des gleichzeitigen Markierungszeitraums geändert hat, der den verbleibenden SATB-Protokollpuffer und alle Aktualisierungen verarbeitet und alle nicht zugegriffenen Überlebenden herausfindet Objekte .

Im CMS-Collector verwendet das Remarking inkrementelle Aktualisierungen, während G1 einen anfänglichen Snapshot-Algorithmus SATB-Algorithmus verwendet, der schneller als CMS ist: Snapshot-at-the-beginning.

Die SATB erstellt zu Beginn der Markierung eine Momentaufnahme der überlebenden Objekte, um sicherzustellen, dass alle Müllobjekte in der gleichzeitigen Markierungsphase durch Momentaufnahmen identifiziert werden können. Wenn die Zuweisungsanweisung auftritt, ändert die Anwendung ihren Objektgraphen, dann muss die JVM das überschriebene Objekt aufzeichnen, sodass der Write-Before-Fence den Wert im SATB-Protokoll oder -Puffer aufzeichnet, bevor sich die Referenz ändert (jeder Thread belegt ausschließlich ein SATB-Puffer, zunächst mit 256 Datensätzen). Wenn der Speicherplatz erschöpft ist, weist der Thread einen neuen SATB-Puffer zur weiteren Verwendung zu, und der ursprüngliche Puffer wird zur globalen Liste hinzugefügt. Schließlich überprüft und verarbeitet der gleichzeitige Markierungs-Thread in der gleichzeitigen Markierungsstufe periodisch die Datensätze der globalen Pufferliste während des Markierens und scannt dann das Referenzfeld, um das RSet gemäß dem Markierungsbit des Markierungs-Bitmap-Slice zu aktualisieren, wodurch das korrigiert wird SATB-Fehler.

Der Protokollpuffer von SATB ist derselbe wie der von der Schreibsperre von RSet verwendete Protokollpuffer. Er hat eine zweistufige Struktur und der Wirkungsmechanismus ist derselbe.

(5) Löschen (Aufräumen, STW):

Diese Phase dient hauptsächlich dazu, den Wiederherstellungswert und die Kosten jeder Region zu sortieren und einen Wiederherstellungsplan entsprechend der erwarteten GC-Pausenzeit des Benutzers zu formulieren. (Diese Phase führt weder eine Garbage Collection noch eine Kopie der überlebenden Objekte durch.)

Die detaillierten Vorgänge, die in der Bereinigungsphase durchgeführt werden, lauten wie folgt:

① RSet-Kämmen: Der heuristische Algorithmus definiert je nach Aktivität und RSet-Größe unterschiedliche Ebenen für Partitionen, und die RSet-Mathematik hilft auch, nutzlose Referenzen zu finden.

② Organisieren Sie Heap-Partitionen: Identifizieren Sie Sammlungen von Partitionen der alten Generation mit hohen Wiederherstellungsrenditen (basierend auf freiem Speicherplatz und Pausenzielen) für gemischte Sammlungen;

③ Identifizieren Sie alle inaktiven Partitionen: Finden Sie Partitionen ohne überlebende Objekte, die während der Bereinigungsphase direkt zurückgefordert werden können, ohne auf den nächsten Erfassungszyklus warten zu müssen.

Bildbeschreibung hier einfügen

Wenn Sie den Vorgang der Pflege des Erinnerten Satzes nicht berücksichtigen, kann er in der obigen Abbildung in vier Schritte unterteilt werden (ähnlich wie bei CMS), bei denen die anfängliche Markierung, die gleichzeitige Markierung und die erneute Markierung die gleichen sind wie beim CMS-Sammler , und nur die vierte Stufe des Screenings und der Wiederherstellung ist etwas anders.

3.3.2 Überlebende Objekte kopieren (Evakuierung):

Bildbeschreibung hier einfügen

Wenn G1 die globale gleichzeitige Markierung initiiert, beginnt es nicht sofort mit der gemischten Sammlung. G1 wartet zuerst auf die nächste Sammlung der jungen Generation und bestimmt dann den CSet für die nächste gemischte Sammlung in der Phase der jungen gc-Sammlung

​ Nachdem die globale Markierung abgeschlossen ist, weiß G1, welche alten Regionen den recycelbarsten Müll haben. Sie müssen nur auf den richtigen Zeitpunkt warten, um mit dem gemischten Recycling zu beginnen. Neben dem Recycling der jungen Region werden durch das gemischte Recycling auch einige alte Regionen recycelt (keine Alle alten Regionen recyceln). Gemäß dem Pausenziel ist G1 möglicherweise nicht in der Lage, alle Kandidatenpartitionen für alte Regionen auf einmal zu recyceln, und kann nur mehrere Regionen mit hoher Priorität für die Wiederverwendung auswählen, sodass G1 möglicherweise mehrere aufeinanderfolgende hybride Sammlungen und abwechselnde Ausführung von Anwendungsthreads und diese generiert Die ausgewählte Region ist das CSet, und der einzelne gemischte Wiederherstellungsalgorithmus ist genau derselbe wie der Young GC-Algorithmus oben, außer dass es mehr Speichersegmente der alten Generation in der CSet für die Wiederherstellungssammlung gibt; und der zweite Schritt besteht darin, diese Regionen zu sammeln Die überlebenden Objekte werden in die Weltraumregion kopiert, und diese zurückgewonnenen Regionen werden in die Liste der freien Regionen aufgenommen.

G1 berechnet jedes Mal die Anzahl der Partitionen, die dem CSet hinzugefügt werden, und die Anzahl der gemischten Sammlungen, und in der letzten Sammlung der jungen Generation und der nächsten gemischten Sammlung bestimmt G1 den Partitionssatz, der dem CSet das nächste Mal hinzugefügt werden soll (Choose CSet) und bestimmen, ob der gemischte Erfassungszyklus beendet werden soll.

(1) Nachdem die gleichzeitige Markierung endet, werden die Regionen, die in der alten Generation zu 100 % Müll sind, direkt recycelt, und die Regionen, die nur teilweise Müll sind, werden in 8 Recycling unterteilt (kann durch -XX:G1MixedGCCountTarget festgelegt werden, die Der Standardschwellenwert ist 8), sodass der Wiederherstellungssatz (CSet) von Mixed GC ein Achtel des Altersgedächtnissegments, des Eden-Bereichsspeichersegments und des Survivor-Bereichsspeichersegments enthält.

(2) Da die Speichersegmente der alten Generation standardmäßig 8 Mal recycelt werden, gibt G1 dem Recycling der Speichersegmente mit mehr Müll Priorität. Je höher das Verhältnis von Müll zum Speichersegment ist, desto mehr wird zuerst recycelt. Und ein Schwellenwert bestimmt, ob das Speichersegment zurückgefordert wird -XX:G1MixedGCLiveThresholdPercent, der Standardwert ist 65 %, was bedeutet, dass der Anteil des Datenmülls im Speichersegment 65 % erreichen muss, bevor es zurückgefordert wird. Wenn der Müllanteil zu niedrig ist, bedeutet dies, dass der Anteil der überlebenden Objekte hoch ist und das Kopieren länger dauert.

(3) Gemischtes Recycling muss nicht 8 Mal durchgeführt werden Es gibt einen Schwellenwert -XX:G1HeapWastePercent, der Standardwert ist 10 %, was bedeutet, dass 10 % des gesamten Heap-Speichers verschwendet werden dürfen, was bedeutet, dass wenn Es wurde festgestellt, dass recycelbarer Müll den Heap-Speicher belegt. Wenn der Anteil weniger als 10 % beträgt, wird keine gemischte Wiederherstellung durchgeführt, da GC viel Zeit aufwenden wird, aber der wiederhergestellte Speicher sehr gering ist
Bildbeschreibung hier einfügen

G1 垃圾回收流程小结:Young CG 和 Mixed GC,是G1回收空间的主要活动。当应用开始运行时,堆内存可用空间还比较大,只会在年轻代满时,触发年轻代收集;随着老年代内存增长,当到达 IHOP 阈值 -XX:InitiatingHeapOccupancyPercent(老年代占整堆比,默认45%) 时,G1开始着手准备收集老年代空间。首先经历并发标记周期,识别出高收益的老年代分区。但随后G1并不会马上开启一次混合收集,而是让应用线程先运行一段时间,等待触发一次年轻代收集,在这次STW中,G1将开始整理混合收集周期。接着再次让应用线程运行,当接下来的几次年轻代收集时,将会有老年代分区加入到CSet中,即触发混合收集,这些连续多次的混合收集称为混合收集。

3.4 Vollständige GC:

Wenn G1 keine neue Partition im Heap-Bereich beantragen kann, löst G1 den Garantiemechanismus aus und führt eine Single-Threaded Full GC im STW-Stil aus. Die Full GC markiert, löscht und komprimiert den gesamten Heap und enthält schließlich nur noch reine Überlebensobjekte. Der Parameter -XX:G1ReservePercent (Default 10%) kann im Promotion-Modus Platz für anormale Situationen reservieren, belegt maximal 50% des gesamten Stapels und ist bedeutungslos, wenn er größer ist.

G1 löst in den folgenden Szenarien eine vollständige GC aus und zeichnet „to-space-exhaused“ und „Evacuation Failure“ im Protokoll auf:

  • (1) Beim Kopieren überlebender Objekte aus der Young-Generation-Partition kann keine verfügbare freie Partition gefunden werden
  • (2) Beim Übertragen von überlebenden Objekten von der Partition der alten Generation kann keine verfügbare freie Partition gefunden werden
  • (3) Es ist nicht möglich, im Alter genügend zusammenhängende Partitionen zu finden, wenn große Objekte zugewiesen werden

Da die Anwendung von G1 oft einen relativ großen Heap-Speicher hat, sind die Erfassungskosten von Full GC sehr hoch, und das Auftreten von Full GC sollte vermieden werden

3.5 Dreifarben-Markierungsalgorithmus

Der Drei-Farben-Markierungsalgorithmus stellt einen wichtigen Algorithmus in der gleichzeitigen Erfassungsphase dar. Es ist eine nützliche Methode, um den Tracking-Kollektor zu beschreiben, und es kann verwendet werden, um die Korrektheit des Kollektors abzuleiten. Zunächst unterteilen wir Objekte in drei Typen.

  • Schwarz: Das Stammobjekt oder das Objekt und seine Kinder werden gescannt
  • Grau: Das Objekt selbst wird gescannt, aber die Unterobjekte innerhalb dieses Objekts wurden noch nicht gescannt
  • Weiß: Objekte, die nicht gescannt wurden Nach dem Scannen aller Objekte sind die Objekte, die schließlich weiß sind, unerreichbare Objekte, dh Abfallobjekte

Im Folgenden verwenden wir eine Reihe von Entwicklungsdiagrammen, um unser Verständnis des Dreifarben-Markierungsalgorithmus zu vertiefen.Wenn der GC beginnt, Objekte zu scannen, scannen Sie die Objekte gemäß den folgenden Schritten:

3.5.1 Der normale Ablauf des Dreifarben-Markierungsalgorithmus:

(1) Das Stammobjekt wird auf Schwarz gesetzt und die untergeordneten Objekte werden auf Grau gesetzt:

Bildbeschreibung hier einfügen

(2) Fahren Sie fort, ausgehend von Grau zu traversieren, und setzen Sie die Objekte mit gescannten Unterobjekten auf Schwarz.

Bildbeschreibung hier einfügen

(3) Nach dem Durchqueren aller erreichbaren Objekte werden alle erreichbaren Objekte schwarz. Nicht erreichbare Objekte sind weiß und müssen bereinigt werden.

Bildbeschreibung hier einfügen

3.5.2 Auffälligkeiten des Dreifarben-Markierungsalgorithmus:

Wenn die Anwendung während des Markierungsvorgangs ausgeführt wird, kann sich der Zeiger des Objekts ändern. In diesem Fall werden wir auf ein Problem stoßen: das Problem des Objektverlusts. Betrachten wir die folgende Situation, wenn der Garbage Collector die folgende Situation scannt

Bildbeschreibung hier einfügen

An diesem Punkt führt die Anwendung Folgendes aus:

A.c=C
B.c=null

Auf diese Weise wird das Zustandsdiagramm des Objekts wie folgt:

Bildbeschreibung hier einfügen

Zu diesem Zeitpunkt, wenn der Garbage Collector erneut markiert und scannt, sieht es so aus:
Bildbeschreibung hier einfügen

Offensichtlich ist C zu diesem Zeitpunkt weiß, was als Müll betrachtet wird und aufgeräumt werden muss, was offensichtlich unvernünftig ist. Wie stellen wir also sicher, dass die von GC markierten Objekte nicht verloren gehen, wenn die Anwendung läuft? Es gibt zwei Möglichkeiten:

  • Objekt zum Zeitpunkt des Einfügens aufzeichnen
  • Objekte aufzeichnen, wenn sie gelöscht werden

Zufällig entspricht dies zwei unterschiedlichen Implementierungen von CMS und G1:

( 1) CMS verwendet inkrementelles Update (Incremental update): Solange ein Verweis auf ein weißes Objekt gefunden wird, das einem Feld eines schwarzen Objekts in der Schreibsperre zugeordnet ist, wird das weiße Objekt grau, d. Aufnehmen, wenn eingefügt.

(2) G1 verwendet die STAB-Methode (Snapshot-at-the-Beginn): Alle Objekte beim Löschen aufzeichnen, es hat drei Schritte:

  • ① Erstellen Sie eine Momentaufnahme des überlebenden Objekts, wenn Sie mit dem Markieren beginnen
  • ② Während der gleichzeitigen Markierung werden alle geänderten Objekte in die Warteschlange eingereiht (in der Schreibsperre werden die Objekte, auf die alle alten Referenzen zeigen, nicht weiß).
  • ③ Möglicherweise gibt es kostenlosen Müll, der beim nächsten Mal eingesammelt wird

4. Nachteile des G1-Kollektors

(1) Wenn die Pausenzeit zu kurz ist, kann es dazu führen, dass jede ausgewählte Recycling-Sammlung nur einen kleinen Teil des Heap-Speichers belegt und die Sammelgeschwindigkeit des Sammlers allmählich nicht mehr mit der Verteilungsgeschwindigkeit des Zuordners Schritt halten kann. Dies führt dazu, dass sich Müll langsam ansammelt und schließlich dazu führt, dass der Heap-Speicherplatz voll ist, was Full GC auslöst und die Leistung beeinträchtigt.

(2) G1 ist sowohl in der Speichernutzung, die durch die Speicherbereinigung erzeugt wird, als auch in der zusätzlichen Ausführungslast, wenn das Programm läuft, höher als CMS.

(3) CMS ist höchstwahrscheinlich auf G1 in Anwendungen mit kleinem Speicher zurückzuführen. Daher wird der CMS-Kollektor bei kleinem Speicher verwendet, und der G1-Kollektor kann im Fall von großem Speicher verwendet werden (der G1-Kollektor ist mehr als 6 GB).

Referenzartikel:

https://www.cnblogs.com/lsgxeva/p/10231201.html

https://blog.csdn.net/weixin_43899069/article/details/117996701

https://blog.csdn.net/coderlius/article/details/79272773

https://www.jianshu.com/p/aef0f4765098

Ich denke du magst

Origin blog.csdn.net/qq_46312987/article/details/125074757
Empfohlen
Rangfolge