Die Verwendung schwacher Referenzen ist etwas, von dem ich noch nie eine Implementierung gesehen habe. Daher versuche ich herauszufinden, was der Anwendungsfall für sie ist und wie die Implementierung funktionieren würde. Wann mussten Sie ein WeakHashMap
oder verwenden WeakReference
und wie wurde es verwendet?
java
weak-references
18Rabbit
quelle
quelle
Antworten:
Schwache Referenzen verstehen , Ethan Nicholas
quelle
WeakHashMap
.WeakReference
gegenSoftReference
Ein klarer Unterschied ist der Unterschied zwischen a
WeakReference
und aSoftReference
.Grundsätzlich a
WeakReference
wird a von der JVM eifrig GC-d sein , sobald das referenzierte Objekt keine festen Verweise darauf hat. EinSoftReference
d-Objekt hingegen wird in der Regel vom Garbage Collector zurückgelassen, bis der Speicher wirklich wiederhergestellt werden muss.Ein Cache, in dem die Werte gespeichert sind
WeakReference
s wäre ziemlich nutzlos (in aWeakHashMap
sind es die Schlüssel, auf die schwach verwiesen wird).SoftReferences
sind nützlich, um die Werte zu umbrechen, wenn Sie einen Cache implementieren möchten, der mit dem verfügbaren Speicher wachsen und schrumpfen kann.quelle
Eine häufige Verwendung von
WeakReference
s undWeakHashMap
s ist insbesondere das Hinzufügen von Eigenschaften zu Objekten. Gelegentlich möchten Sie einem Objekt einige Funktionen oder Daten hinzufügen, aber Unterklassen und / oder Kompositionen sind keine Option. In diesem Fall ist es naheliegend, eine Hashmap zu erstellen, die das Objekt, das Sie erweitern möchten, mit der Eigenschaft verknüpft, die Sie hinzufügen möchten . Wenn Sie die Immobilie benötigen, können Sie sie einfach in der Karte nachschlagen. Wenn jedoch die Objekte, die Sie hinzufügen, häufig zerstört und erstellt werden, können viele alte Objekte in Ihrer Karte viel Speicherplatz beanspruchen.Wenn Sie
WeakHashMap
stattdessen a verwenden, verlassen die Objekte Ihre Karte, sobald sie vom Rest Ihres Programms nicht mehr verwendet werden. Dies ist das gewünschte Verhalten.Ich musste dies tun, um einige Daten hinzuzufügen
java.awt.Component
, um eine Änderung in der JRE zwischen 1.4.2 und 1.5 zu umgehen. Ich hätte es beheben können, indem ich jede Komponente, an der ich interessiertJButton
warJFrame
, in Unterklassen unterteilt hätte (,,,JPanel
....), aber das war viel einfacher mit viel weniger Code.quelle
Ein weiterer nützlicher Fall für
WeakHashMap
undWeakReference
ist eine Listener-Registrierungsimplementierung .Wenn Sie etwas erstellen, das bestimmte Ereignisse abhören möchte, registrieren Sie normalerweise einen Listener, z
Wenn der
manager
Speicher Ihren Listener mit a speichertWeakReference
, bedeutet dies, dass Sie das Register nicht entfernen müssen, z. B. mit a,manager.removeListener(myListenerImpl)
da es automatisch entfernt wird, sobald Ihr Listener oder Ihre Komponente, die den Listener enthält, nicht mehr verfügbar ist.Natürlich können Sie Ihren Listener immer noch manuell entfernen, aber wenn Sie dies nicht tun oder vergessen, führt dies nicht zu einem Speicherverlust und verhindert nicht, dass Ihr Listener Müll sammelt.
Wo kommt
WeakHashMap
das ins Bild?Die Listener-Registrierung, die registrierte Listener als
WeakReference
s speichern möchte, benötigt eine Sammlung zum Speichern dieser Referenzen. Es gibt keineWeakHashSet
Implementierung in der Standard-Java-Bibliothek nur a,WeakHashMap
aber wir können die letztere leicht verwenden, um die Funktionalität der ersten zu "implementieren":Damit wird
listenerSet
ein neues Listener registrieren müssen Sie nur an die Set hinzuzufügen, und auch wenn es ausdrücklich nicht entfernt wird, wenn der Hörer wird nicht mehr Bezug genommen wird , wird sie automatisch von der JVM entfernt werden.quelle
WeakHashMap
besteht, wann immer Sie einHashMap
Objekt benötigen . Wow, Sie müssen hashmap.remove nie manuell ausführen , da Elemente automatisch entfernt werden, sobald das Objekt außerhalb des Gültigkeitsbereichs liegt! Buchstäblich Magie! Solch ein hässlicher magischer Hack ist eine komplette Gesichtspalme .WeakReference
vereinfacht die Codebasis erheblich und vermeidet unnötige Fehler im Zusammenhang mit dem fehlgeschlagenen Abbestellen. Was für ein Nachteil?Dieser Blog-Beitrag demonstriert die Verwendung beider Klassen: Java: Synchronisieren auf einer ID . Die Verwendung geht ungefähr so:
IdMutextProvider bietet ID-basierte Objekte zum Synchronisieren. Die Anforderungen sind:
Dies wird mithilfe einer internen Speicherkarte vom Typ erreicht:
Das Objekt ist sowohl Schlüssel als auch Wert. Wenn nichts außerhalb der Karte einen harten Verweis auf das Objekt hat, kann es Müll gesammelt werden. Die Werte in der Karte werden mit harten Referenzen gespeichert, daher muss der Wert in eine WeakReference eingeschlossen werden , um einen Speicherverlust zu verhindern. Dieser letzte Punkt wird im Javadoc behandelt .
quelle
Wenn Sie beispielsweise alle Objekte verfolgen möchten, die von einer bestimmten Klasse erstellt wurden. Damit diese Objekte weiterhin mit Müll gesammelt werden können, führen Sie anstelle der Objekte selbst eine Liste / Karte mit schwachen Verweisen auf die Objekte.
Wenn mir jetzt jemand Phantomreferenzen erklären könnte, wäre ich glücklich ...
quelle
Wie oben erwähnt, wird eine schwache Referenz so lange gehalten, wie eine starke Referenz existiert.
Eine beispielhafte Verwendung wäre die Verwendung von WeakReference in Listenern, sodass die Listener nicht mehr aktiv sind, sobald der Hauptverweis auf ihr Zielobjekt weg ist. Beachten Sie, dass dies nicht bedeutet, dass die WeakReference aus der Listener-Liste entfernt wird. Eine Bereinigung ist weiterhin erforderlich, kann jedoch beispielsweise zu festgelegten Zeiten durchgeführt werden. Dies hat auch den Effekt, dass verhindert wird, dass das abgehörte Objekt starke Referenzen enthält und schließlich eine Quelle des Aufblähens des Gedächtnisses ist. Beispiel: Swing-GUI-Komponenten, die auf ein Modell verweisen, das einen längeren Lebenszyklus als das Fenster hat.
Während wir wie oben beschrieben mit Zuhörern spielten, stellten wir schnell fest, dass Objekte aus Sicht eines Benutzers "sofort" gesammelt werden.
quelle
WeakReferences
dein Kommentar ist völlig falsch!Eine reale Verwendung, die ich für WeakReferences hatte, ist, wenn Sie ein einzelnes, sehr großes Objekt haben, das selten verwendet wird. Sie möchten es nicht im Speicher behalten, wenn es nicht benötigt wird. Wenn ein anderer Thread dasselbe Objekt benötigt, möchten Sie auch nicht zwei davon im Speicher haben. Sie können irgendwo einen schwachen Verweis auf das Objekt und in den Methoden, die es verwenden, harte Verweise behalten. Wenn beide Methoden abgeschlossen sind, wird das Objekt gesammelt.
quelle
Ich habe eine Google-Codesuche nach "new WeakHashMap ()" durchgeführt.
Ich habe eine Reihe von Übereinstimmungen aus dem GNU-Klassenpfad-Projekt und
quelle
Mit schwachem Hashmap können Sie ein ressourcenfreies Caching für die umfangreiche Objekterstellung implementieren.
Beachten Sie jedoch, dass es nicht wünschenswert ist, veränderbare Objekte zu haben. Ich habe es verwendet, um Abfrageergebnisse (deren Ausführung etwa 400 ms dauert) in einer Textsuchmaschine zwischenzuspeichern, die selten aktualisiert wird.
quelle