Search code examples
javalisthashmapgarbage-collectionweak-references

Understanding WeakReferences


In the following code...

public class MyObject {
    public static Map<String, WeakReference<MyObject>> cache = new HashMap<>();
    public static ReferenceQueue<MyObject> queue = new ReferenceQueue<>();
    public MyObject(String... args) {
        //define variables...
        cache.put(args[0], new WeakReference<>(this, queue));
    }
    // getters and setters
}

If MyObjects are continuously created, since cache contains only weak references, will the garbage collector eventually remove items from cache? Will those items become null? Is there a better way of caching objects? My objective is to store discord messages so I don't have to fetch them again.


Solution

  • WeakReferences (once understood) are not magic, and often even easily miss-used. One such example is in your case. First of all of declaring an explicit ReferenceQueue<MyObject> is kind of no use to you, which implies that you want to push code "from here and there" to make it work; this is not a good strategy.

    The idea of a week references is not complicated. Once a GC cycle sees that some instance is weakly referenced (non strong references to it exist), it can simply reclaim that memory and start returning null from WeakReference::get. To get to your example, when some MyObject instance is going to be weakly referenced, your:

    map.get("whatever").get()
    

    will start to return null. But the Map.Entry will still be present in the HashMap. There is no auto-magic clean-up. Even WeakHashMap is no magic.

    There are many "other" ways to cache things, it's complicated to say without more details, which would be appropriate for your case. There is guava, a last-recently used cache like LinkedHashMap, etc.