The use of weak references is something that I've never seen an implementation of so I'm trying to figure out what the use case for them is and how the implementation would work. When have you needed to use a WeakHashMap
or WeakReference
and how was it used?
相关问题
- Delete Messages from a Topic in Apache Kafka
- Jackson Deserialization not calling deserialize on
- How to maintain order of key-value in DataFrame sa
- StackExchange API - Deserialize Date in JSON Respo
- Difference between Types.INTEGER and Types.NULL in
One distinction to be clear on is the difference between a
WeakReference
and aSoftReference
.Basically a
WeakReference
will be GC-d by the JVM eagerly, once the referenced object has no hard references to it. ASoftReference
d object on the other hand, will tend to be left about by the garbage collector until it really needs to reclaim the memory.A cache where the values are held inside
WeakReference
s would be pretty useless (in aWeakHashMap
, it is the keys which are weakly referenced).SoftReferences
are useful to wrap the values around when you want to implement a cache which can grow and shrink with the available memoryUnderstanding Weak References, Ethan Nicholas
Another useful case for
WeakHashMap
andWeakReference
is a listener registry implementation.When you create something which wants to listen to certain events, usually you register a listener, e.g.
If the
manager
stores your listener with aWeakReference
, that means you don't need to remove the register e.g. with amanager.removeListener(myListenerImpl)
because it will be automatically removed once your listener or your component holding the listener becomes unavailable.Of course you still can manually remove your listener, but if you don't or you forget it, it will not cause a memory leak, and it will not prevent your listener being garbage collected.
Where does
WeakHashMap
come into the picture?The listener registry which whishes to store registered listeners as
WeakReference
s needs a collection to store these references. There is noWeakHashSet
implementation in the standard Java library only aWeakHashMap
but we can easily use the latter one to "implement" the functionality of the first one:With this
listenerSet
to register a new listener you just have to add it to the set, and even if it is not removed explicitly, if the listener is no longer referenced, it will be removed automatically by the JVM.If you for example want to keep track of all objects created of a certain class. To still allow these objects to be garbage collected, you keep a list/map of weak references to the objects instead of the objects themselves.
Now if someone could explain phantom-references to me, I'd be happy...
One Common use of
WeakReference
s andWeakHashMap
s in particular is for adding properties to objects. Occasionally you want to add some functionality or data to an object but subclassing and/or composition are not an option in that case the obvious thing to do would be to create a hashmap linking the object you want to extend to the property you want to add. then whenever you need the property you can just look it up in the map. However, if the objects you are adding properties to tend to get destroyed and created a lot, you can end up with a lot of old objects in your map taking up a lot of memory.If you use a
WeakHashMap
instead the objects will leave your map as soon as they are no longer used by the rest of your program, which is the desired behavior.I had to do this to add some data to
java.awt.Component
to get around a change in the JRE between 1.4.2 and 1.5, I could have fixed it by subclassing every component I was interested int (JButton
,JFrame
,JPanel
....) but this was much easier with much less code.As stated above, weak reference are held for as long as a strong reference exists.
An example usage would be to use WeakReference inside listeners, so that the listeners are no longer active once the main reference to their target object is gone. Note that this does not mean the WeakReference is removed from the listeners list, cleaning up is still required but can be performed, for example, at scheduled times. This has also the effect of preventing the object listened to from holding strong references and eventually be a source of memory bloat. Example: Swing GUI components refering a model having a longer lifecycle than the window.
While playing with listeners as described above we rapidly realised that objects get collected "immediately" from a user's point of view.