Even though weak references are massively useful features available for fairly long time, I think they are pretty overlooked. ( Yeah, I am pretty bemused by getting multiple "WeakReference? huh! whats that?!" responses on a single day.) So, lets refresh on what weak references are and what they do.
In short, weak references can save you from a lot of problems in case of
unintentional object retention. If you don't understand "Unintentional Object Retention" mumbo-jumbo, here is a scenario for you.
Lets say, you need to use gigantic images in your application. But, as you know loading images each time from disk is pretty expensive, you decided to cache it. And as a sane person, you don't want the gigantic images using up a large chunk of memory when there is no reference to it. Now, how can you do that? If you use normal reference to the image ( to place it in vector or hash map or in your custom cache class ), when GC will run, it will find that it has at least a reference to that image and would refrain itself from finalizing and reclaiming the memory. Now what you can do is, keeping some kind of in house count of the references that point to that image and when there is no other reference pointing, you can remove the holding reference from your cache store making it eligible for garbage collection. Is it fun to mimic the garbage collector? Hell, No !
Here comes the mighty weak reference into play. To put simply weak references are not strong enough to force the referent object to remain in memory. Another mumbo-jumbo? Well, lets go into details.
Each ordinary reference in Java is a strong reference. What make them strong is the way they interact with GC. More particularly, if an object is reachable through a chain of strong reference it will not be claimed by GC. So for two ordinary references
x and
y, the following statement
x = y;
will make sure that the object to which
y points would be kept in memory as long as
x is reachable.
But, for a weak reference, that is not the case. If all the references to a particular object are weak references ( we call this situation
"weakly reachable"), then garbage collector is eligible to claim the object. So if you use
WeakReference, like the following
WeakReference<SomeOtherRef> weakReference = new WeakReference(someOtherRef);
you are making sure that garbage collector's reachability has been increased and later you can get the reference by using
weakReference.get();
The point to remember is that it is not enough strong to prevent from garbage collection, so don't surprise if
get() all on a sudden, starts returning
null.
So, by now you have got what you need for that caching mechanism. In your caching store house, you will use
WeakReference so that when there is no other strong references, the gigantic image is gracefully removed by the GC.
Java provides more control over garbage collection by providing
PhantomReference,
SoftReference,
ReferenceQueue and
WeakHashMap. But I think I have enough for today, so all these have to wait.