In der Java Virtual Machine wird der Speicher von Objekten und Arrays im Heap zugewiesen, und der vom Garbage Collector wiederhergestellte Hauptspeicher befindet sich im Heap-Speicher. Wenn die dynamisch erstellten Objekte oder Arrays während der Ausführung des Java-Programms nicht rechtzeitig recycelt werden und sich weiter ansammeln, ist der Heap-Speicher irgendwann voll, was zu OOM führt.
JVM bietet einen Garbage-Collection-Mechanismus, der als GC-Mechanismus bezeichnet wird. Durch den GC-Mechanismus können Müllobjekte im Heap während des Betriebs kontinuierlich recycelt werden, wodurch der normale Betrieb des Programms sichergestellt wird.
Wir alle wissen, dass sich die sogenannten „Müll“-Objekte auf Objekte beziehen, die während der Ausführung unseres Programms nicht mehr nützlich sind, also Objekte, die nicht mehr nützlich sind länger am Leben. Wie kann man also beurteilen, ob es sich bei den Objekten im Heap um „Müll“ oder nicht mehr lebende Objekte handelt?
Jedes Objekt verfügt über ein Referenzzählattribut, das verwendet wird, um zu speichern, wie oft das Objekt referenziert wurde. Wenn die Anzahl der Referenzen 0 ist, bedeutet dies, dass auf das Objekt nicht verwiesen wurde, das Objekt nicht verwendet wird und als Müllobjekt bestimmt werden kann. Diese Methode weist jedoch einen großen Fehler auf: Sie kann das Problem gegenseitiger Referenzen oder Zirkelverweise zwischen Objekten nicht lösen: Wenn zwei Objekte aufeinander verweisen, haben sie keine Referenzbeziehung zu anderen Objekten und haben dieselbe Nummer Anzahl der Referenzen ist nicht 0, daher wird es nicht recycelt, aber tatsächlich sind diese beiden Objekte nicht mehr nützlich.
Um Probleme zu vermeiden, die durch die Verwendung der Referenzzählung verursacht werden, verwendet Java die Erreichbarkeitsanalysemethode, um Müllobjekte zu ermitteln.
Auf diese Weise kann man sich die Referenzbeziehung aller Objekte als Baum vorstellen. Vom Wurzelknoten GC aus werden alle referenzierten Objekte im Baum durchlaufen Objekte, die sich nicht am Knoten befinden, sind ein nicht erreichbares Objekt.
Welche Art von Objekt kann also als Wurzelknoten von GC verwendet werden?
Objekte, auf die im Stapel der virtuellen Maschine verwiesen wird (lokale Variablentabelle im Frame-Stack)
Objekte, auf die durch statische Eigenschaften im Methodenbereich verwiesen wird
Objekt, auf das Konstanten im Methodenbereich verweisen
Objekt, auf das JNI im lokalen Methodenstapel verweist
Der Garbage-Collection-Mechanismus, unabhängig davon, ob er die Referenzzählmethode oder die Erreichbarkeitsanalysemethode verwendet, hängt mit der Referenz des Objekts zusammen:
Starke Referenzen – Bei den meisten Referenzen, die wir verwenden, handelt es sich tatsächlich um starke Referenzen, und dies ist die am häufigsten verwendete Referenz. Wenn ein Objekt über eine starke Referenz verfügt, bedeutet dies, dass es sich in einem erreichbaren Zustand befindet und vom Garbage Collector niemals recycelt wird. Selbst wenn der Systemspeicher sehr knapp ist, würde die Java Virtual Machine lieber einen OutOfMemoryError
-Fehler auslösen und das verursachen Das Programm muss abnormal beendet werden, anstatt es wiederzuverwenden. Das Objekt, auf das durch eine starke Referenz verwiesen wird. Daher sind starke Referenzen eine der Hauptursachen für Java-Speicherlecks.
Soft-Referenz – Ein Objekt hat nur eine Soft-Referenz, wenn genügend Speicherplatz vorhanden ist, wird der Speicher dieser Objekte vom Garbage Collector nicht zurückgefordert wird zurückgefordert. Solange der Garbage Collector es nicht sammelt, kann das Objekt vom Programm verwendet werden.
Schwache Referenz – ein Objekt hat nur eine schwache Referenz, was einer Entbehrlichkeit ähnelt. Eine schwache Referenz ähnelt einer weichen Referenz, weist jedoch einen niedrigeren Referenzpegel auf. Der Unterschied zwischen schwachen Referenzen und weichen Referenzen besteht darin, dass Objekte mit nur schwachen Referenzen einen kürzeren Lebenszyklus haben. Während der Garbage-Collector-Thread den Speicherbereich in seinem Zuständigkeitsbereich scannt, wird, sobald ein Objekt mit nur schwachen Referenzen gefunden wird, dessen Speicher zurückgefordert, unabhängig davon, ob der aktuelle Speicherplatz ausreicht.
Dummy-Referenz – Ein Objekt enthält nur eine virtuelle Referenz, dann ist es dasselbe, als hätte es keine Referenz und kann jederzeit vom Garbage Collector recycelt werden. Virtuelle Referenzen werden hauptsächlich verwendet, um die Aktivitäten von Objekten zu verfolgen, die durch Müll gesammelt werden, und wir verwenden sie im Allgemeinen nicht.
Durch den Erreichbarkeitsanalysealgorithmus kann ermittelt werden, welche Objekte recycelt werden müssen.
Zuerst müssen Sie den Objektspeicher markieren, der recycelt werden kann, und dann den recycelten Speicher löschen.
Mark-and-Sweep-Algorithmus (vor dem Recycling)
Mark-and-Sweep-Algorithmus (nach dem Recycling)
Aber in diesem Fall wird während der Ausführung des Programms kontinuierlich Speicher zugewiesen und freigegeben, und es werden viele diskontinuierliche freie Speicherbereiche im Heap generiert, was zu einer Speicherfragmentierung führt. Selbst wenn genügend freier Speicher vorhanden ist, kann auf diese Weise möglicherweise nicht genügend Speicher zugewiesen werden, was zu häufigem GC führen kann, was sich auf die Effizienz auswirkt, oder sogar zu OOM.
Der Unterschied zum Mark-Clear-Algorithmus besteht darin, dass der Mark-Compact-Algorithmus den wiederverwendbaren Speicher nach dem Markieren nicht direkt bereinigt, sondern alle überlebenden Objekte an ein Ende verschiebt und dann löscht den wiederverwendbaren Speicher.
Markierungskollationsalgorithmus (vor dem Recycling)
Markierungskollationsalgorithmus (nach dem Recycling)
Der Vorteil davon ist, dass es keine Speicherfragmentierung verursacht.
Der Kopieralgorithmus muss zuerst den Speicher in zwei Blöcke aufteilen, zuerst einem der Speicherblöcke Speicher zuweisen. Wenn dieser Speicherblock zugewiesen wird, wird die Speicherbereinigung durchgeführt. und dann werden alle überlebenden Objekte in einen anderen Speicherbereich kopiert und der erste Speicherbereich wird gelöscht.
Kopieralgorithmus (vor dem Recycling)
Kopieralgorithmus (nach dem Recycling)
Dies Der Algorithmus führt nicht zu einer Speicherfragmentierung, sondern ist gleichbedeutend damit, dass nur die Hälfte des Speicherplatzes verwendet wird. Gleichzeitig hängt der Replikationsalgorithmus von der Anzahl der überlebenden Objekte ab. Wenn die Anzahl der überlebenden Objekte groß ist, wird die Effizienz des Replikationsalgorithmus stark verringert.
In der Java Virtual Machine kann der Lebenszyklus von Objekten lang oder kurz sein. Der Lebenszyklus der meisten Objekte ist sehr kurz, und nur eine kleine Anzahl von Objekten ist sehr kurz Es bleibt lange im Gedächtnis, sodass Objekte je nach Lebenszyklus in verschiedenen Bereichen platziert werden können. Im Java Virtual Machine-Heap, der den Generationssammlungsalgorithmus verwendet, ist er im Allgemeinen in drei Bereiche unterteilt, in denen jeweils diese drei Objekttypen gespeichert werden:
Neue Generation – die neu erstellten Objekte Während der Code ausgeführt wird, werden im Allgemeinen kontinuierlich neue Objekte erstellt. Viele dieser neu erstellten Objekte sind lokale Variablen und werden bald zu Müllobjekten. Diese Objekte werden in einem Speicherbereich namens „Junge Generation“ abgelegt. Die neue Generation zeichnet sich durch viele Müllobjekte und wenige überlebende Objekte aus.
Alte Generation – einige Objekte wurden sehr früh erstellt und wurden nach mehreren GCs nicht recycelt, haben aber immer überlebt. Diese Objekte werden in einem Bereich platziert, der als alte Generation bezeichnet wird. Das Merkmal der alten Generation ist, dass es viele überlebende Objekte und wenige Müllobjekte gibt.
Permanente Generierung – einige Objekte, die im Lebenszyklus der virtuellen Maschine dauerhaft existieren, wie z. B. einige statische Objekte, Konstanten usw. Diese Objekte werden in einem Bereich platziert, der als permanente Generation bezeichnet wird. Das Merkmal der permanenten Generierung besteht darin, dass diese Objekte im Allgemeinen keine Speicherbereinigung erfordern und überleben, während die virtuelle Maschine ausgeführt wird. (Vor Java 1.7 wurden die permanenten Generierungsobjekte im Methodenbereich gespeichert. Die permanenten Generierungsobjekte im Java 1.7-Methodenbereich wurden auf den Heap verschoben. In Java 1.8 wurde die permanente Generierung aus dem Heap entfernt. Dieser Speicher ist der Metaspace. )
Der Generationssammlungsalgorithmus führt auch eine Speicherbereinigung basierend auf der neuen Generation und der alten Generation durch.
Für den Bereich der neuen Generation werden in jedem GC viele Müllobjekte recycelt und nur wenige werden überleben. Daher wird der Kopierrecycling-Algorithmus verwendet und die wenigen verbleibenden überlebenden Objekte können während der GC kopiert werden.
Im Bereich der neuen Generation werden Kopieren und Recycling nicht im Verhältnis 1:1 durchgeführt, sondern im Verhältnis 8:1:1 in drei Bereiche aufgeteilt: Eden, SurvivorA und SurvivorB . Eden bedeutet „Garten Eden“ und beschreibt die vielen neuen Objekte, die dort geschaffen wurden. Der Bereich „Survivor“ bezieht sich auf Überlebende, also Objekte, die nach GC überlebt haben.
Der Eden-Bereich stellt der Außenwelt Heap-Speicher zur Verfügung. Wenn der Eden-Bereich fast voll ist, wird Minor GC (New Generation GC) durchgeführt, die überlebenden Objekte werden im SurvivorA-Bereich platziert und der Eden-Bereich wird geräumt Wenn der Eden-Bereich wieder gefüllt ist, wird er der Außenwelt weiterhin zur Verfügung gestellt Eden-Bereich und SurvivorA-Bereich gleichzeitig, und die überlebenden Objekte werden gleichzeitig in den SurvivorB-Bereich gelegt. Räumen Sie den Eden-Bereich und den SurvivorA-Bereich gleichzeitig auf Stellen Sie der Außenwelt Heap-Speicher zur Verfügung und wiederholen Sie den obigen Vorgang, dh nachdem der Eden-Bereich gefüllt ist, werden der Eden-Bereich und ein bestimmter Survivor-Bereich Die überlebenden Objekte werden in einem anderen Survivor-Bereich platziert >
Wenn ein Survivor-Bereich gefüllt ist und noch Objekte vorhanden sind, die nicht kopiert wurden, oder wenn einige Objekte 15 Mal wiederholt werden. Wenn der Bereich der alten Generation voll ist, werden die verbleibenden Objekte im Bereich der alten Generation platziert Der Bereich der alten Generation wird ebenfalls gefüllt. Eine Haupt-GC (GC der alten Generation) wird durchgeführt, um eine Speicherbereinigung für den Bereich der alten Generation durchzuführen.GC_CONCURRENT: Wenn der Heap-Speicher unserer Anwendung eine bestimmte Menge erreicht oder fast voll ist, löst das System automatisch eine GC-Operation aus, um den Speicher freizugeben.
GC_EXPLICIT: Zeigt an, dass der GC ausgelöst wird, wenn die Anwendung die System.gc-, VMRuntime.gc-Schnittstelle aufruft oder das SIGUSR1-Signal empfängt.
GC_BEFORE_OOM: Zeigt an, dass der GC durch den letzten Versuch ausgelöst wird, bevor er sich darauf vorbereitet, eine OOM-Ausnahme auszulösen.
Das obige ist der detaillierte Inhalt vonDetaillierte Grafik- und Texterklärung des Garbage-Collection-Mechanismus virtueller Maschinen in Java. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!