Monday, September 18, 2006

Something about Memory Leaks:Part-I

One of the best features of java has been automatic memory management. Unlike C++, where memory has to be released manually and memory management has always been a part of program logic, java frees the programmer from this hasle.But we must understand that JVM is not so much like the Oracle of The Matrix who knows everything and every intension of the programmer .The JVM takes the responsibility to free the memory which is not in use by the program anymore but off course,when it finds so .The programmer is solely responsible to discard all the references to an object when the need expires. Thus the logical lifetime and the actual lifetime of an object must be equal. An object is created on the heap and during the execution of the program, many references are created which point to that same object,but unless and until all the references has been discarded by the program, JVM can not interfere to release the memory space although the object has no use. The leaky code below is one of such situations:


import java.util.*;

public class Registry

{

private static HashMap registry= new HashMap();

public static synchronized void register(Listener listner,Action action)

{

registry.put(listener,action);

}

public static synchronized void deRegister(Listener listener)

{

registry.remove(listener);

}

public static synchronized void broadcast()

{

Iterator itr=map.keySet().iterator();

while(itr.hasNext())

{

Listener listener=(Listener)itr.next;

listener.recieveAction(map.get(listener));

}

}

}

public class AnotherClass

{

public void doSomeWork()

{

Listener listener = new Listener();

Registry.register(listener,new Action("do something"));

Registry.broadcast();

}

public static void main(String[]args)

{

AnotherClass another = new AnotherClass();

another.doSomeWork();

}

}

In the above code, the scope of the Listener object is method level, as the method doSomeWork() completes, the Listener object should ideally become garbage collected but it will not be so.Why? Because, the Registry still has a reference to this Listener object, so if it is indeed intended that the Listener object should become garbage collected after broadcasting, the Listener should deregister itself from Registry. In other words, the programmer has to manually manage the memory allocation and deallocation of Listener object, the JVM will just guaranty that after deregistration, the object will definitely be wiped off the Heap.


This type of unintentional object retention can be quite troublesome . A common workaround for such situations is to use WeakHashMap of java's collection package.WeakHashMap keeps the keys as weak references, thus the garbage collector can claim the memory space held by an object when the only reference to the object is the key of the WeakHashMap.The above leaky code can be fixed by just replacing HashMap with WeakHashMap in the Registry class, so even if AnotherClass does not call deRegister() method, the memory can be freed as the only reference left will be the key of the WeakHashMap of the Registry Class.

4 comments:

Anonymous said...

good work. looking for more

Anonymous said...

This is as lame as it can get.....

Anonymous said...

please research the topic before you post such crappy stuff....

Anonymous said...

I agree with what Mr. Anonymous1 and Anonymous2 said.... go back to where you came from FOB!