Schwache Referenzen in Java

1. Übersicht

In diesem Artikel werfen wir einen Blick auf das Konzept einer schwachen Referenz - in der Java-Sprache.

Wir werden erklären, was dies sind, wofür sie verwendet werden und wie man richtig mit ihnen arbeitet.

2. Schwache Referenzen

Ein schwach referenziertes Objekt wird vom Garbage Collector gelöscht, wenn es schwach erreichbar ist.

Eine schwache Erreichbarkeit bedeutet, dass auf ein Objekt weder starke noch weiche Referenzen verweisen . Das Objekt kann nur durch Überqueren einer schwachen Referenz erreicht werden.

Zunächst löscht der Garbage Collector eine schwache Referenz, sodass auf den Referenten nicht mehr zugegriffen werden kann. Dann wird die Referenz in eine Referenzwarteschlange gestellt (falls eine zugehörige vorhanden ist), von der wir sie erhalten können.

Gleichzeitig werden ehemals schwach erreichbare Objekte finalisiert.

2.1. Schwache vs weiche Referenzen

Manchmal ist der Unterschied zwischen schwachen und weichen Referenzen unklar. Weiche Referenzen sind im Grunde genommen ein großer LRU-Cache. Das heißt, wir verwenden weiche Referenzen, wenn der Referent gute Chancen hat, in naher Zukunft wiederverwendet zu werden .

Da eine weiche Referenz als Cache fungiert, ist sie möglicherweise weiterhin erreichbar, auch wenn der Referent selbst dies nicht ist. Tatsächlich kann eine weiche Referenz nur dann gesammelt werden, wenn:

  • Der Referent ist nicht gut erreichbar
  • Auf die Soft-Referenz wird in letzter Zeit nicht zugegriffen

Daher kann eine weiche Referenz für Minuten oder sogar Stunden verfügbar sein, nachdem der Referent nicht mehr erreichbar ist. Andererseits ist eine schwache Referenz nur verfügbar, solange ihre Referenz noch vorhanden ist.

3. Anwendungsfälle

Wie in der Java-Dokumentation angegeben, werden schwache Referenzen am häufigsten verwendet, um kanonisierende Zuordnungen zu implementieren . Ein Mapping wird als kanonisiert bezeichnet, wenn es nur eine Instanz eines bestimmten Werts enthält. Anstatt ein neues Objekt zu erstellen, wird das vorhandene Objekt im Mapping nachgeschlagen und verwendet.

Natürlich ist die am meisten bekannte Verwendung dieser Referenzen die WeakHashMap Klasse . Es ist die Implementierung der Map- Schnittstelle, bei der jeder Schlüssel als schwache Referenz auf den angegebenen Schlüssel gespeichert wird. Wenn der Garbage Collector einen Schlüssel entfernt, wird auch die diesem Schlüssel zugeordnete Entität gelöscht.

Weitere Informationen finden Sie in unserem Leitfaden zu WeakHashMap.

Ein weiterer Bereich, in dem sie verwendet werden können, ist das Lapsed Listener-Problem .

Ein Herausgeber (oder ein Betreff) enthält starke Verweise auf alle Abonnenten (oder Zuhörer), um sie über Ereignisse zu informieren, die stattgefunden haben. Das Problem tritt auf, wenn ein Listener sich nicht erfolgreich von einem Publisher abmelden kann.

Daher kann ein Listener nicht durch Müll gesammelt werden, da ein starker Verweis darauf weiterhin für einen Publisher verfügbar ist. Folglich können Speicherlecks auftreten.

Die Lösung des Problems kann ein Thema sein, das einen schwachen Bezug zu einem Beobachter hat, der es dem ersteren ermöglicht, Müll zu sammeln, ohne sich abmelden zu müssen (beachten Sie, dass dies keine vollständige Lösung ist und einige andere Probleme einführt, die dies nicht sind hier behandelt).

4. Arbeiten mit schwachen Referenzen

Schwache Referenzen werden durch die Klasse java.lang.ref.WeakReference dargestellt . Wir können es initialisieren, indem wir einen Referenten als Parameter übergeben. Optional können wir eine java.lang.ref.ReferenceQueue bereitstellen :

Object referent = new Object(); ReferenceQueue referenceQueue = new ReferenceQueue(); WeakReference weakReference1 = new WeakReference(referent); WeakReference weakReference2 = new WeakReference(referent, referenceQueue); 

Der Referent einer Referenz kann mit der get- Methode abgerufen und mit der clear- Methode manuell entfernt werden :

Object referent2 = weakReference1.get(); weakReference1.clear(); 

Das Muster für das sichere Arbeiten mit dieser Art von Referenzen ist das gleiche wie bei weichen Referenzen:

Object referent3 = weakReference2.get(); if (referent3 != null) { // GC hasn't removed the instance yet } else { // GC has cleared the instance }

5. Schlussfolgerung

In diesem kurzen Tutorial haben wir uns mit dem einfachen Konzept einer schwachen Referenz in Java befasst - und uns auf die gängigsten Szenarien konzentriert, um diese zu verwenden.