Weak Reference

Weak Reference holds reference to an object (referent)

public Map<Task, TaskStatus> taskStatus
    = Collections.synchronizedMap(new HashMap<Task, TaskStatus>());

if only out standing reference to referent are weak then referent becomes candidate for GC

WeakReference.get returns the referent
it can return null because
1- WeakReference.clear is called, or
2- refrent is garbage collected because it has no reachable strong references.

always check for null to get referent from WeakReference.get

WeakHashMap uses weak reference for __keys__ (not for values)

so an entry stays in the WeakHashMap as long as there is a reachable strong reference to __key__
and only after that “strong reference” to __value__ will released.

life time of __value__ is under the control of (with other things) the outstanding strong reference to __key__ in weakhashmap

When WeakReference.get() is called, it returns a strong reference to the referent (if it is still alive), so there is no need to worry about the mapping disappearing in the body of the while loop because the strong reference keeps it from being garbage collected.

When you add a mapping to a WeakHashMap, remember that it is possible that the mapping could “fall out” later because the key is garbage collected. In that case, get() returns null, making it even more important than usual to test the return value of get() for null.

Map<Socket,User> m = new WeakHashMap<Socket,User>();

here life time of User object is controlled by lifetime of Socket object (if this map is the only one hold any outstanding strong reference to User) since __key__ is weak referenced, User object will become gc’able as soon as (its key) Socket object becomes gc’able.

gc’able – no reachable strong reference exists.

==============
Reference Queue
==============
something must also be done to prune the dead entries from the Map after the key object has been collected. Otherwise, the Map would simply fill up with entries corresponding to dead keys. it could still cause the application to run out of memory because the Map.Entry and value objects would not be collected, even if the key is.

Dead mappings could be eliminated by periodically scanning the Map, calling get() on each weak reference, and removing the mapping if get() returns null. But this would be inefficient if the Map has many live entries. It would be nice if there was a way to be notified when the referent of a weak reference is garbage collected, and that is what reference queues are for.

Reference queues are the garbage collector’s primary means of feeding back information to the application about object life cycle.

WeakReference has 2 Constructors

    
    WeakReference(T referent) 
              // Creates a new weak reference that refers to the given object.
    
    WeakReference(T referent, ReferenceQueue<? super T> q) 
              // Creates a new weak reference that refers to the given object and is registered with the given queue.

How does GC notify that referent in a WeakRefernce object has become candidate for GC?

lets say WeakReference object was created with the second constructor, that takes ReferenceQueue as argument.
When referent becomes candidate for GC the “WeakReference object” (not referent) will be added (enqueue) to ReferenceQueue queue.
so by polling on ReferenceQueue application can find out what “WeakReference object”‘s referent has become candidate for GC and do the appropriate clean up, like remove entry for that “WeakReference object” from WeakRefrenceMap (remember __key__ in WeakRefrenceMap is weak)
RefrenceQueue offer following dequeuing —
polled, timed blocking, and untimed blocking.
All Reference types are cleared before they are enqueued, so the thread handling the post-mortem cleanup never has access to the referent object, only the Reference object.

WeakHashMap has a private method called expungeStaleEntries() that is called during most Map operations, which polls the reference queue for any expired references and removes the associated mappings.

WeakHashMap.get method returns “strong reference” to the referent, so we dont have to worry if reference will become invalid after we got from WeakHashMap.

=====================================
Soft Reference
=====================================
If the only remaining references to an object are weak or soft references, then that object is said to be softly reachable.

Soft references are a way of saying to the garbage collector, “As long as memory isn’t too tight, I’d like to keep this object around. But if memory gets really tight, go ahead and collect it and I’ll deal with that.”. The garbage collector is required to clear all soft references before it can throw OutOfMemoryError. The key to whether a soft reference can be used is whether an application can recover from the loss of the data being cached.

If you need to cache more than a single object, you might use a Map, but you have a choice as to how to employ soft references. You could manage the cache
as a
Map<K, SoftReference>
or as a
SoftReference<Map>.

The latter option is usually preferable, as it makes less work for the collector and allows the entire cache to be reclaimed with less effort when memory is in high demand.

Weak references are sometimes mistakenly used instead of soft references for building caches, but this will result in poor caching performance. In practice, weak references will get cleared fairly quickly after the object becomes weakly reachable — usually before the cached object is needed again — as minor garbage collections run frequently.

Reference queues are not as useful with soft references as with weak references, but they could be used to raise a management alert that the application is starting to run low on memory.