„Hallo! Ich habe beschlossen, dir noch eine kleine Lektion über die Müllabfuhr zu erteilen.“

Wie Sie bereits wissen, überwacht die Java-Maschine selbst, wenn ein Objekt unnötig wird, und löscht es.

„Ja. Du und Rishi habt mir vorhin davon erzählt. Ich erinnere mich nicht an die Einzelheiten.“

„OK. Dann lass es uns noch einmal durchgehen.“

Müllabfuhr – 1

„Sobald ein Objekt erstellt wird, weist die JVM ihm Speicher zu. Das Interesse am Objekt wird mithilfe von Referenzvariablen überwacht.  Ein Objekt kann während der Garbage Collection gelöscht werden, d. h. der Prozedur, durch die Speicher freigegeben wird, wenn keine Variablen vorhanden sind, die auf das Objekt verweisen Objekt.

„Erzählen Sie mir ein wenig über den Garbage Collector – was er ist und wie er funktioniert.“

„OK. Früher fand die Speicherbereinigung im Hauptthread statt. Alle 5 Minuten oder öfter. Wenn jemals nicht genügend freier Speicher vorhanden war, unterbrach die Java-Maschine alle Threads und löschte nicht verwendete Objekte.“

„Dieser Ansatz wurde jedoch inzwischen aufgegeben. Der Garbage Collector der nächsten Generation arbeitet hinter den Kulissen und in einem separaten Thread. Dies wird als gleichzeitige Garbage Collection bezeichnet.“

„Ich verstehe. Wie genau wird die Entscheidung getroffen, ein Objekt zu löschen oder nicht?“

„Nur die Anzahl der Verweise auf ein Objekt zu zählen, ist nicht sehr effektiv – es kann Objekte geben, die aufeinander verweisen, aber von keinem anderen Objekt referenziert werden.“

„Also verfolgt Java einen anderen Ansatz.  Java unterteilt Objekte in erreichbare und nicht erreichbare.  Ein Objekt ist erreichbar (lebendig), wenn es von einem anderen erreichbaren (lebenden) Objekt referenziert wird. Die Erreichbarkeit wird anhand von Threads bestimmt. Laufende Threads gelten immer als erreichbar (lebendig). , auch wenn niemand darauf verweist.

„Okay. Ich glaube, ich verstehe.“

„Wie erfolgt die eigentliche Speicherbereinigung – das Löschen unnötiger Objekte?“

„Es ist ganz einfach. In Java ist der Speicher per Konvention in zwei Teile geteilt, und wenn es Zeit für die Speicherbereinigung ist, werden alle lebenden (erreichbaren) Objekte in einen anderen Teil des Speichers kopiert und der alte Speicher wird vollständig freigegeben.“

„Das ist ein interessanter Ansatz. Referenzen müssen nicht gezählt werden: Kopieren Sie alle erreichbaren Objekte, und alles andere ist Müll.“

„Es ist etwas komplizierter. Java-Programmierer haben herausgefunden, dass Objekte normalerweise in zwei Kategorien unterteilt werden: langlebig (die während der gesamten Laufzeit des Programms vorhanden sind) und kurzlebig (die in Methoden und zur Ausführung von „lokalen Objekten“ benötigt werden » Operationen).

„Es ist viel effizienter, langlebige Objekte von kurzlebigen zu trennen. Dazu musste eine Möglichkeit gefunden werden, die Langlebigkeit des Objekts zu bestimmen.“

„Also haben sie den gesamten Speicher in „Generationen“ unterteilt. Es gibt Objekte der ersten Generation, Objekte der zweiten Generation usw. Jedes Mal, wenn der Speicher gelöscht wird, wird der Generationszähler um 1 erhöht. Wenn bestimmte Objekte in mehreren Generationen existieren, dann sind sie es gelten als langlebig.“

„Der Garbage Collector ist heute ein sehr komplexer und effizienter Teil von Java. Viele seiner Teile arbeiten heuristisch – basierend auf Algorithmen, die Vermutungen anstellen. Daher hört er dem Benutzer oft nicht zu.“

"Bedeutung?"

„Java verfügt über ein Garbage Collector ( GC )-Objekt, das mit der System.gc ()-Methode aufgerufen werden kann.“

„Sie können System.runFinalization() auch verwenden , um Aufrufe der finalize-Methoden der zu löschenden Objekte zu erzwingen. Tatsache ist jedoch, dass dies laut Java-Dokumentation weder garantiert, dass die Garbage Collection gestartet wird, noch, dass finalize( )-Methode aufgerufen wird.  Der Garbage Collector entscheidet, wann und wofür er aufgerufen wird. "

„Whoa! Gut zu wissen.“

„Aber es gibt noch mehr. Wie Sie wissen, verweisen in Java einige Objekte auf andere. Dieses Referenznetzwerk wird verwendet, um zu bestimmen, ob ein Objekt gelöscht werden soll.“

„Und schauen Sie. Java hat spezielle Referenzen, mit denen Sie diesen Prozess beeinflussen können. Es gibt spezielle Wrapper-Klassen dafür. Hier sind sie:“

SoftReference  ist eine Soft-Referenz.“

WeakReference  ist eine schwache Referenz.“

PhantomReference ist eine Phantomreferenz.“

„Äh... Das erinnert mich an innere Klassen, verschachtelte Klassen, verschachtelte anonyme Klassen und lokale Klassen. Die Namen sind unterschiedlich, aber es ist überhaupt nicht klar, wozu sie dienen.“

„Sagen Sie, Amigo, Sie sind Programmierer geworden. Jetzt ärgern Sie sich über die Klassennamen und sagen: „Sie sind nicht informativ genug und es ist unmöglich, mit einem Namen(!) zu bestimmen, was diese Klasse macht, wie, und warum"."

„Wow. Das ist mir gar nicht aufgefallen. Aber es ist so offensichtlich.“

„OK. Genug der Worte. Lassen Sie mich Ihnen etwas über SoftReferences erzählen.“

„Diese Referenzen wurden speziell für das Caching entwickelt, können aber auch für andere Zwecke verwendet werden – ganz im Ermessen des Programmierers.“

„Hier ist ein Beispiel für eine solche Referenz:“

Beispiel
// Create a Cat object
Cat cat = new Cat();

// Create a soft reference to a Cat object
SoftReference<Cat> catRef = new SoftReference<Cat>(cat);

// Now only the catRef soft reference points at the object
cat = null;

// Now the ordinary cat variable also references the object
cat = catRef.get();

// Clear the soft reference
catRef.clear();

„Wenn die einzigen Verweise auf ein Objekt weich sind, dann lebt es weiter und wird als ‚weich erreichbar‘ bezeichnet.“

"Aber!  Ein Objekt, auf das nur durch Soft-Referenzen verwiesen wird, kann vom Garbage Collector gelöscht werden, wenn das Programm nicht über genügend Speicher verfügt.  Wenn das Programm plötzlich nicht mehr über genügend Speicher verfügt, löscht der Garbage Collector alle Objekte, bevor eine OutOfMemoryException ausgelöst wird wird durch Soft-Referenzen referenziert und wird erneut versuchen, dem Programm Speicher zuzuweisen.

„Angenommen, ein Clientprogramm fordert häufig verschiedene Daten von einem Serverprogramm an. Das Serverprogramm kann eine SoftReference verwenden , um einige davon zwischenzuspeichern. Wenn Objekte, die durch Softreferenzen vor dem Tod geschützt werden, einen großen Teil des Speichers beanspruchen, werden sie vom Garbage Collector einfach gelöscht alle. Es ist wunderschön!“

„Ja. Mir hat es selbst gefallen.“

„Nun, eine kleine Ergänzung: Die SoftReference- Klasse verfügt über zwei Methoden. Die get()-Methode gibt das von SoftReference referenzierte Objekt zurück . Wenn das Objekt vom Garbage Collector gelöscht wurde, beginnt die get ()-Methode plötzlich, null zurückzugeben.“

„Der Benutzer kann die SoftReference auch explizit löschen, indem er die Methode clear() aufruft. In diesem Fall wird die schwache Verbindung innerhalb des SoftReference- Objekts zerstört.“

„Das ist alles für den Moment.“

„Danke für die interessante Geschichte, Ellie. Sie war wirklich sehr interessant.“