Wednesday, December 5, 2007

Weak Reference in Java

WeakReferences have been there in Java since JDK 1.2. But in my personal opinion this powerful facility is often underutilized.
In this blog, I will give an introduction about the concept of WeakReference and how to use WeakReference.

Concept of Weak Reference:
WeakReference is a reference which allows us to access the object but it does not prevent the garbage collector from garbage collecting the same object in order to reclaim memory. That is the object pointed to by a WeakReference can be garbage collected even if the reference is not set to null. This ensures that all the WeakReference’d objects are garbage collected before the JVM throws OutOfMemory Exception.
This special ability of WeakReference has some important implications in performance optimization, fixing memory leaks etc.

Application of WeakReference:

One application of WeakReference is in maintaining cache.

Problem:
Let us assume want to maintain a cache of error messages which are stored in database. As the exception occurs, we will fetch the error message from database, add it to the cache and pass the message to user. Next time for same error, we will fetch it from cache instead of database.

We do not know beforehand, when to free up a message so that we do not run out of memory.

Solution:
In this case, we will create and add WeakReferences to the error message fetched instead of regular references. This will ensure that the unused error message objects are garbage collected before we run out of memory.

How to use WeakReference?

Let us assume we have a large object.
Following code will create a WeakReference for the object:

Object someLargeObject = new Object();
WeakReference weakLargeObject = new WeakReference(someLargeObject);

Here, the reference weakLargeObject is WeakReference.
The someLargeObject pointed to by this reference will definitely be garbage collected before JVM will run short of memory.

How to access the Object pointed to by Weak Reference?
TO get the actual object pointed to by WeakReference, we use the get() method.
So in our example, we will use
Object largeObject = weakLargeObject.get();

How do we know where the object pointed to by WeakReference is garbage collected or not?
To test if the WeakReference’d object was garbage collected or not, we will check the reference returned by get().
So in our example,
if(weakLargeObject.get() == null)
{
//Object was garbage collected
}

This is how weak reference can be implemented and used.

2 comments:

Sourav Dutta said...

I think one disadvantage of Weak Reference will be that we need to have a strong reference of the object(that you have declared as weak reference)while you need it.Otherwise it might be garbage collected.We are never sure when the garbage collector will run.

Dinar Senjit said...

We must not keep a strong reference to the object declared as WeakReference. Otherwise, it will hold on to object and JVM will not be able to reclaim the object when required. This undermines the whole objective of cache using WeakReference.
Getting object garbage collected when required is the feature of WeakReference. get() method is used to know if the object was garbage collected or not.