Wann möchten Sie ein WeakHashMap oder eine WeakReference verwenden?
-
03-07-2019 - |
Frage
Die Verwendung von schwachen Referenzen ist etwas, das ich nie eine Implementierung so gesehen habe ich versuche die Verwendung Fall für sie, um herauszufinden, was ist und wie die Umsetzung funktionieren würde. Wann haben Sie einen WeakHashMap
oder WeakReference
verwenden benötigt und wie wurde es verwendet?
Lösung
Ein Problem mit starken Referenzen ist Caching, insbesondere bei sehr großen Strukturen wie Bilder. Angenommen, Sie eine Anwendung, die arbeiten muss mit vom Benutzer gelieferten Bildern, wie die Website-Design-Tool, das ich arbeite. Natürlich wollen Sie diese zwischenzuspeichern Bilder, weil sie von der Festplatte geladen sehr teuer ist und Sie möchten vermeiden die Möglichkeit, zwei mit Kopien der (potentiell riesigen) Bild im Speicher auf einmal.
Da ein Bild-Cache soll verhindern, dass wir Nachladen Bilder, wenn wir absolut nicht brauchen, werden Sie schnell erkennen, dass der Cache sollte immer enthält einen Verweis auf eine beliebige Bild, das bereits im Speicher befindet. Mit gewöhnliche starke Referenzen, obwohl, daß Referenz selbst die Kraft wird Bild im Speicher zu verbleiben, die irgendwie bestimmen erfordert, dass Sie, wenn das Bild wird nicht mehr benötigt, in Speicher und entfernt sie aus dem Cache-Speicher, so dass wird es, die für garbage collection. Sie sind gezwungen, duplizieren Sie das Verhalten des Mülls Kollektor und manuell bestimmen, ob oder nicht sollte ein Objekt sein, in Speicher.
Verständnis Schwache Referenzen , Ethan Nicholas
Andere Tipps
Eine Unterscheidung klar zu sein, auf ist der Unterschied zwischen einem WeakReference
und einem SoftReference
.
Im Grunde ein WeakReference
wird GC-d von der JVM mit Spannung, wenn das referenzierte Objekt hat keine hart Verweise darauf. Ein SoftReference
d Objekt auf der anderen Seite, wird dazu neigen, vom Garbage Collector gelassen werden über, bis es wirklich die Erinnerung muss zurückzufordern.
Ein Cache, wo die Werte innerhalb WeakReference
s gehalten werden würde ziemlich nutzlos sein (in einem WeakHashMap
, ist es die Schlüssel, die schwach referenziert werden). SoftReferences
sind nützlich, um die Werte um zu wickeln, wenn Sie einen Cache implementieren möchten, die mit dem verfügbaren Speicher kann wachsen und schrumpfen
Eine gemeinsame Verwendung von WeakReference
s und WeakHashMap
s insbesondere Objekten zum Hinzufügen von Objekten. Gelegentlich möchten Sie einige Funktionen oder Daten zu einem Objekt hinzufügen, aber Subklassifizieren und / oder Zusammensetzung sind keine Option in diesem Fall die offensichtliche Sache zu tun wäre, eine hashmap zu erstellen, das Objekt verbindet Sie auf die Eigenschaft erweitern möchten Sie hinzufügen möchten . dann, wenn Sie die Eigenschaft benötigen, können Sie es einfach in der Karte sehen. Wenn jedoch die Objekte, die Sie Eigenschaften hinzufügen neigen dazu, viel zu bekommen zerstört und erstellt hat, können Sie mit einer Menge alter Gegenstände in Ihrer Karte eine Menge Speicher Aufnahme beenden.
Wenn Sie eine WeakHashMap
stattdessen die Objekte verwenden, wird Ihre Karte verlassen, sobald sie nicht mehr durch den Rest des Programms verwendet, die das gewünschte Verhalten ist.
Ich hatte dies zu tun, einige Daten in dem java.awt.Component
um eine Änderung in der JRE zwischen 1.4.2 und 1.5 zu bekommen, ich hätte fixierte jede Komponente von Subklassen Ich war interessiert int (JButton
, JFrame
, JPanel
.. ..), aber das war viel einfacher, mit viel weniger Code.
Ein weiterer nützlicher Fall für WeakHashMap
und WeakReference
ist eine Zuhörer Registrierungs Implementierung .
Wenn Sie etwas schaffen, die auf bestimmte Ereignisse hören möchte, in der Regel Sie einen Listener registrieren, z.
manager.registerListener(myListenerImpl);
Wenn die manager
speichert Ihre Zuhörer mit einem WeakReference
, die Sie bedeutet nicht das Register entfernen müssen z.B. mit einem manager.removeListener(myListenerImpl)
, weil es automatisch, sobald Ihre Zuhörer entfernt werden oder die Komponente den Hörer hält nicht mehr verfügbar ist.
Natürlich können Sie noch manuell Zuhörer entfernen, und , wenn Sie nicht tun, oder Sie vergessen es, wird es nicht zu einem Speicherverlust verursachen, und es wird nicht Ihre Zuhörer Müll gesammelt verhindern.
Wo kommt ins Bild WeakHashMap
kommen?
Die Hörer-Registrierung, die registrierten Hörer speichern whishes als WeakReference
s eine Sammlung dieser Verweise speichern muss. Es gibt keine WeakHashSet
Implementierung in der Standard-Java-Bibliothek nur ein WeakHashMap
aber wir können leicht die letztere verwenden, um „zu implementieren“, um die Funktionalität des ersten:
Set<ListenerType> listenerSet =
Collections.newSetFromMap(new WeakHashMap<ListenerType, Boolean>());
Mit diesem listenerSet
einen neuen Listener registrieren Sie müssen nur fügen Sie es zu dem Satz, und auch wenn es nicht explizit entfernt wird, wenn der Hörer wird nicht mehr Bezug genommen wird, wird sie automatisch von der JVM entfernt werden.
Dieser Blog-Eintrag die Verwendung beiden Klassen demonstriert: Java: auf einer ID synchronisieren. Die Nutzung geht in etwa so:
private static IdMutexProvider MUTEX_PROVIDER = new IdMutexProvider();
public void performTask(String resourceId) {
IdMutexProvider.Mutex mutext = MUTEX_PROVIDER.getMutex(resourceId);
synchronized (mutext) {
// look up the resource and do something with it
}
}
IdMutextProvider bietet id-basierte Objekte zu synchronisieren, auf. Die Anforderungen sind:
- muss einen Verweis auf das gleiche Objekt zurück, für die gleichzeitige Verwendung von Ersatz IDs
- muss ein anderes Objekt für unterschiedliche IDs zurückgeben
- keine Freigabemechanismus (Objekte werden nicht an den Anbieter zurückgegeben)
- darf nicht auslaufen (nicht genutzte Objekte sind, die für die Garbage Collection)
Dies wird erreicht, eine interne Speicher Karte des Typs mit:
WeakHashMap<Mutex, WeakReference<Mutex>>
Das Objekt ist sowohl Schlüssel und 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 sind mit harten Referenzen gespeichert, so dass der Wert muss in einem gewickelt werden WeakReference ein Speicherleck zu verhindern. Dieser letzte Punkt wird in der javadoc bedeckt .
Wenn Sie zum Beispiel behalten wollen den Überblick über alle Objekte einer bestimmten Klasse erstellt. Um noch diese Objekte zu erlauben werden, Müll gesammelt, halten Sie eine Liste / Karte schwachen Verweis auf die Objekte anstelle der Objekte selbst.
Nun, wenn jemand Phantomverweis mir erklären könnte, ich würde glücklich sein ...
Wie oben erwähnt, schwache Referenz wird so lange gehalten, wie eine starke Referenz vorhanden ist.
Ein Beispiel für die Verwendung wäre WeakReference innerhalb Hörer zu verwenden, so dass die Zuhörer nicht mehr aktiv sind, sobald der Haupt Bezug auf ihr Zielobjekt weg ist. Beachten Sie, dass dies nicht bedeutet, die WeakReference aus dem Hörer Liste entfernt wird, wird Reinigung noch erforderlich, kann aber durchgeführt werden, beispielsweise zu festgelegten Zeiten. Dies hat auch den Effekt der Verhinderung der Gegenstand hörte von starken Referenzen halten und schließlich eine Quelle des Speicher aufblasen sein. Beispiel:. Swing-GUI-Komponenten beziehen ein Modell eine längere Lebensdauer als das Fenster mit
Während mit den Hörern zu spielen, wie oben beschrieben wir realisierten schnell, dass Objekte „sofort“ des von einem Benutzer Sicht gesammelt erhalten.
Eine reale Welt Verwendung ich für WeakReferences hatte, wenn Sie ein einzelnes, sehr großes Objekt, das selten verwendet wird. Sie wollen nicht, es im Speicher zu halten, wenn es nicht gebraucht wird; aber, wenn ein anderer Thread das gleiche Objekt benötigt, Sie wollen nicht zwei von ihnen in Erinnerung entweder. Sie können irgendwo auf dem Objekt einen schwachen Bezug zu halten, und harte Referenzen in den Methoden, die sie verwenden; wenn die Methoden sowohl Finish, wird das Objekt gesammelt werden.
Ich habe eine Google-Suche nach "neuer WeakHashMap ()".
Ich habe ein paar Spiele aus dem GNU Classpath Projekt und
- Apache XBean Projekt: WeakHashMapEditor.java
- Apache Lucene Projekt: CachingWrapperFilter.java
Sie können eine Ressource freie Caching für expansive Objekterstellung verwenden WeakHashMap zu implementieren.
Beachten Sie jedoch, dass es nicht veränderbare Objekte haben, ist wünschen. Ich benutzen es, Abfrageergebnisse (die nehmen etwa 400 ms für die Ausführung) zu einer Text-Suchmaschine cachen, die selten aktualisiert wird.