8.1 Schwache Referenzen in Java

In Java gibt es verschiedene Arten von Referenzen.

Es gibt StrongReference – das sind die häufigsten Links, die wir täglich erstellen.

Object object = new Object();//created an object
object = null;//can now be garbage collected

Und es gibt drei „spezielle“ Arten von Links – SoftReference, WeakReference, PhantomReference. Tatsächlich gibt es zwischen allen Arten von Links nur einen Unterschied – das Verhalten des GC mit den Objekten, auf die er verweist. Wir werden die Besonderheiten jedes Linktyps später ausführlicher besprechen, aber vorerst reichen die folgenden Kenntnisse aus:

  • SoftReference ist eine Soft-Referenz. Wenn der GC erkennt, dass auf ein Objekt nur über eine Kette von Soft-Referenzen zugegriffen werden kann, entfernt er es aus dem Speicher. Vielleicht.
  • WeakReference – eine schwache Referenz. Wenn der GC erkennt, dass ein Objekt nur über eine Kette schwacher Referenzen zugänglich ist, entfernt er es aus dem Speicher.
  • PhantomReference ist eine Phantomreferenz. Wenn der GC erkennt, dass ein Objekt nur über eine Kette von Phantomreferenzen verfügbar ist, entfernt er es aus dem Speicher. Nach mehreren GC-Läufen.

Man kann auch sagen, dass Linktypen einen gewissen Grad an Weichheit aufweisen:

  • Ein regulärer Hardlink ist eine beliebige Variable eines Referenztyps. Wird nicht vom Garbage Collector bereinigt, bevor es nicht mehr verwendet wird.
  • SoftReference . Das Objekt führt nicht dazu, dass der gesamte Speicher aufgebraucht wird – es wird garantiert gelöscht, bevor ein OutOfMemoryError auftritt. Abhängig von der Implementierung des Garbage Collectors möglicherweise früher.
  • Schwache Referenz . Schwächer weich. Verhindert nicht, dass das Objekt entsorgt wird; der Garbage Collector ignoriert solche Verweise.
  • PhantomReference . Wird für die „Tod“-Verarbeitung eines Objekts verwendet: Das Objekt ist nach der Finalisierung verfügbar, bis es durch den Müll gesammelt wird.

Wenn noch nicht klar ist, was der Unterschied ist, dann machen Sie sich keine Sorgen, bald wird sich alles von selbst ergeben. Die Details sind im Detail, und die Details werden folgen.

8.2 WeakReference und SoftReference in Java

Schauen wir uns zunächst den Unterschied zwischen WeakReference und SoftReference in Java an.

Kurz gesagt: Der Garbage Collector gibt den Speicher eines Objekts frei, wenn nur schwache Referenzen darauf verweisen. Wenn SoftReferences auf das Objekt zeigt, wird die Speicherfreigabe freigegeben, wenn die JVM dringend Speicher benötigt.

Dies verschafft SoftReference in bestimmten Fällen einen deutlichen Vorteil gegenüber Strong-Referenzen. SoftReference wird beispielsweise zum Implementieren eines Anwendungscaches verwendet. Daher löscht die JVM zunächst Objekte, auf die nur SoftReferences verweisen.

WeakReference eignet sich hervorragend zum Speichern von Metadaten, beispielsweise zum Speichern eines Verweises auf einen ClassLoader. Wenn keine Klasse geladen ist, sollten Sie nicht auf den ClassLoader verweisen. Aus diesem Grund ermöglicht WeakReference es dem Garbage Collector, seine Arbeit am ClassLoader zu erledigen, sobald der letzte starke Verweis darauf entfernt wird.

WeakReference-Beispiel in Java:

// some object
Student student = new Student();

// weak reference to it
WeakReference weakStudent = new WeakReference(student);

// now the Student object can be garbage collected
student = null;

SoftReference-Beispiel in Java:

// some object
Student student = new Student();

// weak reference to it
SoftReference softStudent = new SoftReference(student)

// now the Student object can be garbage collected
// but this will only happen if the JVM has a strong need for memory
student = null;

8.3 PhantomReference in Java

Die PhantomReference-Instanz wird auf die gleiche Weise wie in den WeakReference- und SoftReference-Beispielen erstellt, wird jedoch selten verwendet.

Eine PhantomReference kann durch Garbage Collection erfasst werden, wenn das Objekt keine starken (Strong), schwachen (WeakReference) oder weichen (SoftReference) Referenzen hat.

Sie können ein Phantom-Referenzobjekt wie folgt erstellen:

PhantomReference myObjectRef = new PhantomReference(MyObject);

PhantomReference kann in Situationen verwendet werden, in denen finalize() keinen Sinn ergibt. Dieser Referenztyp unterscheidet sich von anderen Typen, da er nicht für den Zugriff auf ein Objekt konzipiert ist. Dies ist ein Signal dafür, dass das Objekt bereits finalisiert wurde und der Garbage Collector bereit ist, seinen Speicher zurückzugewinnen.

Dazu stellt der Garbage Collector es zur weiteren Verarbeitung in eine spezielle ReferenceQueue . In der ReferenceQueue werden Objektverweise platziert, um Speicher freizugeben.

Phantomreferenzen sind eine sichere Methode, um festzustellen, ob ein Objekt aus dem Speicher entfernt wurde. Stellen Sie sich beispielsweise eine Anwendung vor, die große Bilder verarbeitet. Nehmen wir an, wir möchten ein Bild in den Speicher laden, wenn es sich bereits im Speicher befindet und für die Speicherbereinigung bereit ist. In diesem Fall möchten wir warten, bis der Garbage Collector das alte Image beendet, bevor wir das neue Image in den Speicher laden.

Hier ist PhantomReference eine flexible und sichere Wahl. Der Verweis auf das alte Bild wird an die ReferenceQueue übergeben, nachdem das alte Bildobjekt zerstört wurde. Sobald wir diesen Link haben, können wir das neue Bild in den Speicher laden.