Friday, December 10, 2010

Weak References

Java or .NET has a feature called garbage collection. That means all unreferenced objects will be garbage collected automatically. Does that mean that there can not be memory leak in Java or .NET? If you say Yes, then you are wrong! poorly written Java or C# code can leak memory. For example, if you create a static dictionary and keep on adding object which are not needed anymore. There is common misunderstanding in C# and Java programmer that whatever not needed, will be garbage collected. But the correct statement is what ever not referenced will be garbage collected. Sometime this difference in understanding leads poor code which leaks memory. There is common mistake of some static object holding the reference to some object which is not needed anymore.

Most of the time leak happens in these two cases:
(1) Static object holding reference to object which no more needed.
(2) Object which has long life span holds the reference to object which has shorter life span.

Ideally you can write clean code to avoid these situations. But there are cases it becomes too difficult to maintain such kind of code. A typical example is WPF event handler. If you have registered a event handler, then object that contains the event handler method will be referenced by the event source. Even if the object is not needed, the event source will keep the reference and hence the object will remain in memory. The simplest solution to un-register the event handler.

There another way is to use weak event handler. The weak event handler will keep the weak reference to the event handler target object.

The weak references are the references which are ignored by garbage collector. If the object has only weak references to it, the garbage collector will collect this.

The weak event handler is implemented using the WeakReference class. Here I am describing the WekReference class and the readers can go ahead and implement weak event handler using WeakReference class.

Here is a Java code with WeakReferece usage
import java.lang.ref.*;

public class Weak
{
    public static void main(String[] args)
    {
        Object obj = new Object();
        WeakReference<Object> weak = new WeakReference<Object>(obj);
        checkReference(weak);

        obj = null;
        // setting obj = null makes the object left with
        // only a weak reference to it.
        // although the object has weak reference,
        // the garbage collector will collect this.
        System.gc();
        checkReference(weak);
    }

    public static void checkReference(WeakReference<Object> weak)
    {
        if(weak.get() != null)
        {
            System.out.println("Object Exists!!");
        }else
        {
            System.out.println("Object Garbage Collected!!");
        }
    }
}

And Here is C# code:
public class Weak
{
    public static void Main()
    {
        object obj = new object();
        WeakReference weak = new WeakReference(obj);
        CheckReference(weak);

        obj = null;
        // setting obj = null makes the object left with
        // only a weak reference to it.
        // although the object has weak reference,
        // the garbage collector will collect this.
        GC.Collect();
        CheckReference(weak);
    }

    public static void CheckReference(WeakReference weak)
    {
        if(weak.IsAlive)
        {
            Console.WriteLine("Object Exists!!");
        }else
        {
            Console.WriteLine("Object Garbage Collected!!");
        }
    }
}

No comments:

Post a Comment