Heim >Java >JavaErste Schritte >Was ist der Garbage-Collection-Mechanismus von JVM?
Der Garbage Collection-Mechanismus von JVM ist GC (Garbage Collection), auch Garbage Collector genannt. Grundprinzipien von GC: Recyceln Sie Objekte, die nicht mehr im Speicher verwendet werden. Die für das Recycling in GC verwendete Methode wird als Collector bezeichnet. Da GC einige Ressourcen und Zeit verbrauchen muss, analysiert Java die Lebenszykluseigenschaften des Objekts und verwendet Objekte In der neuen und alten Generation gesammelt, um die durch GC verursachte Pause für die Anwendung so weit wie möglich zu verkürzen.
Die Betriebsumgebung dieses Tutorials: Windows7-System, Java8-Version, DELL G3-Computer.
Warum eine Speicherbereinigung erforderlich ist
Wenn keine Speicherbereinigung durchgeführt wird, wird der Speicher früher oder später verbraucht, da wir ständig Speicherplatz zuweisen, ohne ihn zu recyceln. Sofern der Speicher nicht unendlich ist, können wir ihn beliebig zuweisen, ohne ihn wiederzuverwenden, aber das ist nicht der Fall. Daher ist eine Müllsammlung erforderlich.
JVM-Garbage-Collection-Prinzip
● Die Sammlung Die Anzahl der Objekte in der alten Generation wird als „Full GC“ bezeichnet. ● Der GC, der durch den aktiven Aufruf von System.gc() im Programm erzwungen wird, ist „Full GC“. Verschiedene Objektreferenztypen. GC verwendet unterschiedliche Methoden zum Recyceln. JVM-Objekte werden in Referenzen unterteilt vier Typen:
● Starke Referenz: Standardmäßig verwenden Objekte starke Referenzen (Instanzen dieses Objekts haben keine anderen Objektreferenzen und werden nur in GC recycelt) ● Weiche Referenz: Weiche Referenz ist der Schlüssel in Java. Es stellt eine Anwendung bereit, die ist besser für Caching-Szenarien geeignet (es wird nur GCed, wenn der Speicher nicht ausreicht)
● Schwache Referenz: Wird während der GC definitiv von GC recycelt
● Virtuelle Referenz: Weil die virtuelle Referenz nur verwendet wird, um zu wissen, ob das Objekt ist GC
Das Objekt ist als Müllmethode markiert
程序计数器
、虚拟机栈
、本地方法栈
、堆区
、方法区
Referenzzählung ist eine frühe Strategie im Garbage Collector. Bei diesem Ansatz verfügt jede Objektinstanz im Heap über einen Referenzzähler. Wenn ein Objekt erstellt wird, wird die Objektinstanz einer Variablen zugewiesen und die Variablenanzahl wird auf 1 gesetzt. Wenn einer anderen Variablen eine Referenz auf dieses Objekt zugewiesen wird, wird der Zähler um 1 erhöht (a = b, dann ist der Zähler der Objektinstanz, auf die b + 1 verweist), aber wenn eine Referenz einer Objektinstanz den Lebenszyklus überschreitet oder ist auf gesetzt. Bei Erreichen eines neuen Werts wird der Referenzzähler der Objektinstanz um 1 dekrementiert. Jede Objektinstanz mit einem Referenzzähler von 0 kann durch Garbage Collection erfasst werden. Wenn eine Objektinstanz der Garbage Collection unterzogen wird, wird der Referenzzähler jeder Objektinstanz, auf die sie verweist, um eins dekrementiert.
Vorteile: Der Referenzzählsammler kann schnell ausgeführt werden und ist mit dem Programmablauf verknüpft. Dies ist vorteilhafter für Echtzeitumgebungen, in denen das Programm nicht für längere Zeit unterbrochen werden muss.
Nachteile: Zirkelbezüge können nicht erkannt werden. Wenn das übergeordnete Objekt einen Verweis auf das untergeordnete Objekt hat, verweist das untergeordnete Objekt wiederum auf das übergeordnete Objekt. Auf diese Weise kann ihr Referenzzähler niemals 0 sein.
Analyse des oben genannten Codes durch Referenzzählmethode:
Der Erreichbarkeitsalgorithmus wird derzeit vom Mainstream verwendet virtuelle Maschinen. Das Programm behandelt alle Referenzbeziehungen als Diagramm, beginnend mit einem Knoten-GC-Wurzeln und sucht nach dem entsprechenden Referenzknoten. Nachdem alle Referenzknoten durchsucht wurden, wird dieser Knoten weiter gesucht gelten als Knoten, auf die nicht verwiesen wurde, d. h. nutzlose Knoten werden als wiederverwertbare Objekte beurteilt.
In der Java-Sprache können folgende Objekte als GC-Roots verwendet werden:
● Objekte, auf die im Stapel der virtuellen Maschine verwiesen wird (lokale Variablentabelle im Stapelrahmen);
● Objekte, auf die durch statische Klassenattribute in der Methode verwiesen wird Bereich;
● Objekte, auf die durch Konstanten im Methodenbereich verwiesen wird.
● Objekte, auf die durch JNI (native Methoden) im lokalen Methodenstapel verwiesen wird.
Es kann gefolgert werden, dass die Objektinstanzen 1, 2, 4 und 6 alle über Objekterreichbarkeit verfügen, dh überlebende Objekte und Objekte, die von GC nicht recycelt werden können. Obwohl die Caprice-Instanzen 3 und 5 direkt verbunden sind, sind keine GC-Roots mit ihnen verbunden, d. h. Objekte, die von GC-Roots nicht erreichbar sind, werden von GC recycelt.
Die Grundidee des Mark-/Clear-Algorithmus ist genau wie sein Name, der in zwei Stufen unterteilt ist: „Mark“ und „ „clear“: Erste Markierung Entfernen Sie alle Objekte, die recycelt werden müssen, und recyceln Sie alle markierten Objekte gleichmäßig, nachdem die Markierung abgeschlossen ist.
Markierungsphase:
Der Prozess des Markierens ist eigentlich der Prozess des zuvor eingeführten Erreichbarkeitsanalysealgorithmus. Er durchläuft alle GC Roots-Objekte und markiert die vom GCRoots-Objekt aus erreichbaren Objekte, normalerweise im Objektheader , notieren Sie es als erreichbares Objekt.
Reinigungsphase:
Der Reinigungsprozess besteht darin, den Heap-Speicher zu durchlaufen. Wenn festgestellt wird, dass ein Objekt nicht als erreichbares Objekt markiert ist (durch Lesen der Objekt-Header-Informationen), wird es recycelt.
Das obige Bild ist ein schematisches Diagramm des Markierungs-/Löschalgorithmus. In der Markierungsphase kann auf Objekt B von Objekt GC Root 1 zugegriffen werden, und auf Objekt E kann von Objekt B aus zugegriffen werden 1 bis B und E sind beide erreichbar. Ebenso sind die Objekte F, G, J und K alle erreichbare Objekte in der Bereinigungsphase.
Wenn der Garbage Collector GC ausführt, müssen alle Java-Ausführungsthreads gestoppt werden (auch „Stop The World“ genannt). Der Grund dafür ist, dass sich die Objektreferenzbeziehung während der Markierungsphase nicht weiter ändern kann Andernfalls kann die Genauigkeit der Ergebnisse der Erreichbarkeitsanalyse nicht garantiert werden. Der Anwendungsthread wird erst dann wieder ausgeführt, wenn die Markierung gelöscht wird.
Nachteile des Markierungs-/Löschalgorithmus:
● Effizienzprobleme
Die beiden Phasen des Markierens und Löschens sind nicht sehr effizient, da beide Phasen die Objekte im Speicher durchlaufen müssen, und zwar um ein Vielfaches die Objekte im Speicher Speicher Die Anzahl der Instanzen ist sehr groß, was zweifellos zeitaufwändig ist, und die Anwendung muss während des GC gestoppt werden, was zu einer sehr schlechten Benutzererfahrung führt.
● Speicherplatzproblem
Nach dem Löschen der Markierung wird eine große Anzahl diskontinuierlicher Speicherfragmente generiert (wie aus dem Bild oben ersichtlich ist, kann dies dazu führen, dass größere benötigte Objekte nicht gefunden werden können). Genug zusammenhängender Speicher muss während der Programmausführung zugewiesen werden, um im Voraus eine weitere Garbage-Collection-Aktion auszulösen.
Der Kopieralgorithmus teilt den verfügbaren Speicher je nach Kapazität in zwei gleich große Blöcke auf und verwendet jeweils einen Block. Wenn dieser Speicherblock erschöpft ist, kopieren Sie die verbleibenden Objekte in einen anderen Speicherblock und bereinigen Sie dann alle Objekte in diesem Speicherblock auf einmal
Der Kopieralgorithmus recycelt jedes Mal den Speicher des gesamten halben Bereichs, wodurch die Zeit zum Durchlaufen der markierten Objekte verkürzt wird. Beim Löschen der verwendeten Bereichsobjekte ist kein Durchlaufen erforderlich, der gesamte Bereichsspeicher wird direkt gelöscht und die verbleibenden Objekte werden auch in der Adressreihenfolge gespeichert, wodurch das Problem der Speicherfragmentierung gelöst wird. Bei der Zuweisung von Objektspeicher müssen keine komplexen Probleme wie die Speicherfragmentierung berücksichtigt werden .
Nachteile des Kopieralgorithmus:
Der Kopieralgorithmus ist einfach und effizient und optimiert die geringe Effizienz und die Speicherfragmentierungsprobleme des Mark- und Clear-Algorithmus. Es gibt Nachteile:
Reduzieren Sie den Speicher auf die Hälfte des Originals Größe, die Hälfte des Speicherplatzes wird verschwendet. Die Kosten sind zu hoch; , und der Zeitaufwand kann nicht ignoriert werden.
Nachteile beim Markieren/Organisieren: ● Ineffizienz: Es müssen nicht nur die überlebenden Objekte markiert werden, sondern auch die Referenzadressen aller überlebenden Objekte müssen organisiert werden, was nicht so effizient ist wie der Kopieralgorithmus.
Eigenschaften: Die neue Generation: Sie wird geboren und verschwindet, und ihre Überlebenszeit ist sehr kurz. Verwenden Sie den Replikationsalgorithmus, um
Alte Generation zu sammeln: Überleben Sie nach mehreren Minor-GCs und haben Sie eine lange Überlebenszeit. Verwenden Sie den Mark/Clear-Algorithmus oder den Mark/Organize-Algorithmus, um die alte Generation zu sammeln.
Die Überlebensrate von Objekten in der alten Generation ist nicht für die Verwendung des Kopieralgorithmus geeignet Bei der Generierung wird der Kopieralgorithmus verwendet, sodass kein zusätzlicher Speicherplatz für die Zuweisung garantiert wird, sodass der Mark/Clean-Algorithmus oder der Mark/Collation-Algorithmus für die Wiederverwertung verwendet werden.
Objekte der neuen Generation „leben und sterben“. Jedes Mal, wenn GC auftritt, wird eine große Anzahl von Objekten sterben und eine kleine Anzahl überlebt. Der Replikationsalgorithmus wird verwendet. Die neue Generation ist in Eden-Bereich und Survivor-Bereich (Survivor from, Survivor to) unterteilt, und das Größenverhältnis beträgt standardmäßig 8:1:1.
Für Objekte der alten Generation wird der Mark-Clear- oder Mark-Complement-Algorithmus verwendet, da die Objektüberlebensrate hoch ist und kein zusätzlicher Platz für die Zuweisungsgarantie vorhanden ist.
Neu generierte Objekte betreten zuerst den Eden-Bereich. Wenn Survivor from ebenfalls voll ist, wird Minor GC (GC der neuen Generation) durchgeführt und die überlebenden Objekte in Eden und Survivor from werden kopiert in Survivor to und dann Eden und Survivor entfernen. Zu diesem Zeitpunkt wird der ursprüngliche Survivor to zum neuen Survivor to. Wenn Survivor beim Kopieren nicht alle überlebenden Objekte aufnehmen kann, werden die Objekte auf der Grundlage der Zuteilungsgarantie der alten Generation kopiert (ähnlich der Kreditgarantie einer Bank). (alte Generation) wird durchgeführt.
Große Objekte gelangen direkt in die alte Generation: Es gibt eine Parameterkonfiguration in der JVM
-XX:PretenureSizeThreshold, die dazu führt, dass Objekte, die größer als dieser Einstellungswert sind, direkt in die alte Generation gelangen. Der Zweck besteht darin, eine große Anzahl von Speicherkopien dazwischen zu vermeiden die Bereiche Eden und Survivor.
Langfristig überlebende Objekte treten in die alte Generation ein: JVM definiert einen Objektalterszähler für jedes Objekt. Wenn das Objekt nach der Geburt von Eden noch überlebt und den ersten Minor GC besteht und vom Überlebenden aufgenommen werden kann, wird es verschoben Der Überlebende und sein Alter sind auf 1 festgelegt. Wenn es einen Minor GC nicht überstanden hat, wird sein Alter um 1 erhöht. Wenn sein Alter ein bestimmtes Alter erreicht (der Standardwert ist 15 Jahre, der über XX:MaxTenuringThreshold festgelegt werden kann), wird es in die alte Generation verschoben . Die JVM verlangt jedoch nicht immer, dass das Alter das maximale Alter erreichen muss, bevor es in die alte Generation befördert wird Bei mehr als der Hälfte des Überlebens werden alle Objekte mit einem Alter größer oder gleich x direkt in die alte Generation aufgenommen. Es ist nicht erforderlich, bis zum Erreichen der maximalen Altersanforderung zu warten.
Generations-Recycling:
Wir verwenden ein Objekt1, um seine Recycling-Trajektorie im Generations-Garbage-Collection-Algorithmus zu veranschaulichen.
1. Objekt1 ist neu erstellt und wurde im Eden-Gebiet der neuen Generation geboren.
2. Minor GC, Objekt1 ist noch am Leben und wurde in den From-Survivor-Bereich verschoben. Es befindet sich zu diesem Zeitpunkt noch in der neuen Generation.
3. Untergeordneter GC, Objekt1 ist noch am Leben. Zu diesem Zeitpunkt wird Objekt1 durch den Kopieralgorithmus in den ToSuv-Bereich verschoben.
4. Minor GC, Objekt1 ist noch am Leben. Zu diesem Zeitpunkt haben die Objekte im gleichen Alter wie Objekt1 noch nicht die Hälfte der Überlebenden erreicht, daher werden zu diesem Zeitpunkt die Bereiche fromSuv und Tosuv ausgetauscht Durch den Kopieralgorithmus werden die überlebenden Objekte nach Tosuv verschoben.
5. Minor GC, Objekt1 ist noch am Leben. Zu diesem Zeitpunkt haben die Objekte im gleichen Alter wie Objekt1 im Überlebenden mehr als die Hälfte der Überlebenden erreicht (der toSuv-Bereich ist voll) und Objekt1 wurde verschoben zum Bereich der alten Generation.
6. Nachdem Objekt1 eine Zeit lang überlebt hat, wird festgestellt, dass Objekt1 GcRoots zu diesem Zeitpunkt nicht erreichen kann und das Raumverhältnis der alten Generation zu diesem Zeitpunkt den Schwellenwert überschritten hat, was MajorGC auslöst (dies kann ebenfalls berücksichtigt werden). wie fullGC, aber es erfordert einen Garbage Collector) Kontakt), Objekt1 wird zu diesem Zeitpunkt recycelt. fullGC wird die Welt stoppen.
In der oben genannten neuen Generation haben wir das Alter des Objekts im Überlebenszustand erwähnt und werden nicht sofort zum Objekt der alten Generation befördert, um übermäßige Auswirkungen auf die alte Generation zu vermeiden Die folgenden Bedingungen können gefördert werden:
1. Nach dem Minor GC beträgt das Alter der im Survivor-Bereich überlebenden Objekte +1. Wenn es (Standard) 15 überschreitet, wird es auf die alte Generation übertragen.
2. Dynamische Objekte: Wenn die Gesamtgröße aller gleichaltrigen Objekte im Überlebensraum mehr als die Hälfte des Überlebensraums beträgt, können Objekte mit einem Grad größer oder gleich diesem Alter direkt in die alte Generation eintreten.
Das obige ist der detaillierte Inhalt vonWas ist der Garbage-Collection-Mechanismus von JVM?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!