Thursday 24 March 2011

Weak and Soft References and the Garbage Collector

Java uses the Garbage Collector to manage memory. It does this by freeing up memory no longer needed by the application ie memory used by objects that are not referenced anymore, in other words, objects that are ‘unreachable’.

Typically, objects are strongly referenced so they remain in memory until no longer reachable,

Customer customer = new Customer();

but there are certain scenarios where you’d want to keep references to objects and also allow them to be garbage collected if needs be eg when memory is at a premium. A solution to this problem is to use Reference Objects.

There are three concrete implementations of the java.lang.ref.Reference<T> class: WeakReference, SoftReference and PhantomReference.

Objects held only by a WeakReference are deemed to be weakly reachable and are therefore eligible for garbage collection. An example of creating a WeakReference is below:

WeakReference<Customer> weakCustomer = new
    WeakReference<Customer>(customer);

To obtain the customer object held by the weak reference, you would call weakCustomer.get(). This will always return the customer object unless the garbage collecter has deemed the object to be weakly reachable and therefore has freed it from memory. In that case, calling the get method will return null;

If you want to hold a collection of the objects that can be garbage collected, then you can use a WeakHashMap. This collection uses weak references as keys, so when the key becomes garbage collected, the entry for that key in the WeakHashMap gets removed. This collection class isn’t synchronized so use Collections.synchronizedMap for a synchronized version, but be beware that whether synchronized or not, the size of the Map may decrease over time as the garbage collector removes entries, so an iterator may return ConcurrentModificationException.

A SoftReference holds onto the object more strongly than a WeakReference and if memory is not a problem the garbage collector will not free up the memory used by objects held by a soft reference.

You can also create another type of reference to an object, a PhantomReference. Calling the get method on such a reference will always return null though thereby preventing you from ‘resurrecting’ the object.  It’s only real use is when you pass a ReferenceQueue into the PhantomReference constructor.

You can pass a ReferenceQueue into the constructor of all the Reference types. It enables you to keep track of objects which have been garbage collected. When the object’s finalize method is called, the object will be placed on the reference queue. This process is called ‘enqueuing’. You then know when it was removed from memory.

In the case of a PhantomReference, passing in a null ReferenceQueue would be a pointless exercise, rendering the creation of the PhantomReference useless.


1 comment:

  1. Nice article , you have indeed covered Garbage Collection in Java in details with sample code and graphics, its indeed a topic which require a deeper understanding than many other java topics.

    Javin
    How Garbage collection works in Java

    ReplyDelete

Note: only a member of this blog may post a comment.