Dieser Artikel stellt hauptsächlich den relevanten Inhalt der Markierung von Java-Recyclingobjekten und den sekundären Markierungsprozess von Objekten vor. Ich werde ihn hier mit Ihnen teilen.
1. Markierung von Gegenständen
1. Was ist eine Markierung? Wie markieren?
Ich glaube, jeder weiß, dass die erste Frage darin besteht, einige tote Gegenstände zu markieren, um die Reinigung des Müllsammlers zu erleichtern. Für die Markierung gibt es im Allgemeinen zwei Methoden: Referenzzählung und Erreichbarkeitsanalyse.
Die Referenzzählung ist relativ einfach zu implementieren. Sie besteht darin, dem Objekt einen Referenzzähler hinzuzufügen, der um 1 erhöht wird wird um 1 dekrementiert. Wenn der Zähler 0 ist, wird er zum Recycling markiert. Dieses Urteil ist sehr effizient, aber viele gängige virtuelle Maschinen verwenden diese Methode nicht, hauptsächlich weil es schwierig ist, das Problem der Zirkelverweise zwischen mehreren Objekten zu lösen. Obwohl sie nicht oft verwendet wird, lohnt es sich dennoch, sie zu lernen!
public class Test { private Object obj; Public static void main(){ Test t1=new Test(); Test t2=new Test(); t1.obj=t2; t2.obj=t1; t1=null; t2=null; //如果对象在这行发生gc,那么t1和t2对象是否能被回收 System.gc(); } }
Die Grundidee der Erreichbarkeitsanalyse ist: Beginnen Sie die Suche von diesen Knoten aus, indem Sie einige Objekte namens „GC Roots“ als Ausgangspunkt verwenden Suchen Sie nach Objekten, die eine direkte oder indirekte Referenzbeziehung zum Knoten haben, und kombinieren Sie diese Objekte in Form von Ketten zu einem „Beziehungsnetzwerk“, auch Referenzkette genannt. Schließlich sammelt der Garbage Collector einige Objekte, die sich nicht in diesem Beziehungsnetzwerk befinden. Wie im Bild gezeigt:
Das mit dem GC Roots-Objekt verbundene Objekt ist definitiv ein lebendiges Objekt, und das Würfelobjekt auf der rechten Seite hat nichts mit GCROOTS zu tun, daher wird es markiert als wiederverwertbares Objekt. Derzeit verwenden gängige kommerzielle virtuelle Maschinen ähnliche Methoden. Welche Objekte können also als „GC Roots“ verwendet werden? In Java gibt es vier Arten von Objekten, die als Referenzobjekte in „GC Roots“ verwendet werden können
1: Stapelrahmen (Substantiv in Kapitel 1). (Im Stapel)
2: Objekt, auf das durch statische Eigenschaften verwiesen wird. (Im Methodenbereich)
3: Objekt, auf das durch eine Konstante verwiesen wird. (Im Methodenbereich)
4: Von JNI referenziertes Objekt im lokalen Methodenstapel. (Im lokalen Methodenstapel)
2. Sekundäres Recycling von Objekten
Ich habe gesagt, dass das Objekt markiert ist, aber das ist nicht der Fall bedeutet, dass es gekennzeichnet ist. Wird es definitiv recycelt? Ich weiß nicht, ob ihr euch daran erinnert, dass die Object-Klasse eine finalize()-Methode hat. Alle Klassen erben die Object-Klasse, daher ist diese Methode standardmäßig implementiert.
Das Funktionsprinzip von Finalize sollte wie folgt aussehen: Sobald der Garbage Collector bereit ist, den vom Objekt belegten Speicherplatz freizugeben, ruft er zuerst finalize() auf und erst beim nächsten Garbage Collection-Prozess , wird es wirklich den Speicher des Objekts zurückgewinnen? Wenn Sie finalize() verwenden, können Sie während der Garbage Collection einige wichtige Aufräumarbeiten durchführen.
Wann wird finalize() aufgerufen?
Es gibt drei Situationen
1. Alle Objekte werden automatisch aufgerufen, wenn sie Garbage Collection sind, beispielsweise wenn System.gc() ausgeführt wird.
2. Das Programm wird beendet. Die finalize-Methode wird einmal für jedes Objekt aufgerufen.
3. Rufen Sie explizit die finalize-Methode auf
Der Zweck dieser Methode ist: Bevor das Objekt recycelt wird, wird die finalize()-Methode des Objekts aufgerufen . Das Recycling bezieht sich hier auf nach der Markierung. Das Problem liegt darin, dass sich ein Objekt nicht mehr im im vorherigen Kapitel erwähnten „Beziehungsnetzwerk“ (Referenzkette) befindet, sondern nach dem Umschreiben durch den Entwickler () und das Objekt erneut zum „Beziehungsnetzwerk“ hinzugefügt, das heißt, das Objekt ist für uns immer noch nützlich und sollte nicht recycelt werden, aber es wurde markiert.
Um dieses Problem anzugehen, besteht der Ansatz der virtuellen Maschine darin, Objekte zweimal zu markieren, also Objekte zu markieren, die sich nicht zum ersten Mal im „Beziehungsnetzwerk“ befinden. Beim zweiten Mal muss zunächst festgestellt werden, ob das Objekt die Methode finalize () implementiert hat. Wenn sie nicht implementiert wurde, wird direkt festgestellt, dass das Objekt recycelbar ist Zuerst wird es in eine Warteschlange gestellt, und ein von der virtuellen Maschine erstellter Prioritätsthread führt es aus, und dann wird eine zweite kleine Markierung durchgeführt. Dieses Mal wird das markierte Objekt tatsächlich recycelt.
Zusammenfassung: Vereinfacht ausgedrückt wird das Objekt zum ersten Mal markiert und die finalize()-Methode des Objekts wird vor dem nächsten GC ausgeführt. Bei der Ausführung der finalize()-Methode wird beurteilt, ob das Objekt die finalize()-Methode implementiert hat. Wenn sie nicht implementiert ist, wird sie direkt gelöscht. Wenn sie implementiert ist, wird das Objekt in eine Warteschlange gestellt, um die finalize()-Methode auszuführen und zum zweiten Mal markiert
im Java-Root-Suchalgorithmus Um die Erreichbarkeit von Objekten zu ermitteln, müssen nicht erreichbare Objekte nicht unbedingt bereinigt werden. Zu diesem Zeitpunkt gibt es eine Probezeit. Um wirklich beurteilen zu können, dass ein Objekt tot ist, muss es mindestens zwei Markierungsprozesse durchlaufen: Wenn das Objekt nach einer Root-Suche feststellt, dass keine Referenzkette mit GC-Wurzeln verknüpft ist, wird dies der Fall sein Zum ersten Mal markieren und nach dem Filtern ist die Filterbedingung, ob dieses Objekt die finalize()-Methode ausführen muss Wenn das Objekt die finalize()-Methode nicht abdeckt, oder die finalize()-Methode wurde von der virtuellen Maschine aufgerufen, die virtuelle Maschine wird in allen Fällen als „Es besteht keine Notwendigkeit, auszuführen“ betrachtet.
Das heißt, wenn ein Objekt die finalize()-Methode überschreibt, wird beurteilt, dass das Objekt zur Ausführung der finalize()-Methode erforderlich ist, dann wird das Objekt in die F-Warteschlange gestellt und Es wird später von einem Finalizer-Thread mit niedriger Priorität ausgeführt, der automatisch von der virtuellen Maschine erstellt wird. Die sogenannte Ausführung bedeutet hier, dass die virtuelle Maschine diese Methode startet, aber nicht verspricht, zu warten, bis die Ausführung abgeschlossen ist. Der Grund dafür: Wenn ein Objekt in der finalize()-Methode langsam ausgeführt wird oder eine Endlosschleife auftritt (im Extremfall), kann dies dazu führen, dass sich andere Objekte in der F-Queue-Warteschlange dauerhaft im Wartezustand befinden oder sogar dazu führen Der gesamte Speicher bis zum Recyclingsystem stürzt ab. Die finalize()-Methode ist die letzte Chance für das Objekt, dem Schicksal des Todes zu entgehen. Später markiert der GC das Objekt in der F-Warteschlange für einen zweiten kleinen Maßstab, wenn das Objekt sich erfolgreich in finalize() speichern möchte. ----Solange Sie es einfach erneut mit irgendetwas in der Referenzkette verknüpfen, wird es aus der Sammlung „kurz vor der Wiederverwertung“ entfernt, wenn es zum zweiten Mal markiert wird, wenn das Objekt dabei nicht entkommt Zeit wird es recycelt. Codebeispiel: Weitere Informationen finden Sie im entsprechenden Kapitel von „Ausführliches Verständnis der Java Virtual Machine“
Zusammenfassung
Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der Markierung recycelter Objekte in Java und des sekundären Markierungsprozesses von Objekten. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!