Tuesday, January 19, 2010

Memory Leak in Dot Net

Memory leaks can occur either in the stack, unmanaged heap, or the managed heap. There are many ways to find out that memory is leaking, like memory increasing in the Task Manager. Before starting to correct the memory problem, you need to determine the kind of memory which is leaking. Perfmon can be used to examine counters such as Process/Private bytes, .NET CLR Memory/# bytes in all heaps, and the .NET CLR LocksAndThreads/# of the current logical thread. If the .NET CLR LocksAndThreads/# is increasing unexpectedly, then the thread stack is leaking. If only Process/Private bytes are increasing but the .NET CLR Memory is not increasing, then unmanaged memory is leaking, else if both are increasing, then managed memory is leaking.

Stack memory
Stack memory gets reclaimed after the method returns. Stack memory can get leaked in two ways. First, a method call consumes a significant amount of stack resources that never returns, thereby never releasing the associated stack frame. The other is by creating background threads and never terminating them, thus leaking the thread stack.

Unmanaged Heap Memory
If the total memory usage is increasing but the .NET CLR memory is not increasing, then unmanaged memory is leaking. Unmanaged memory can leak in several ways - if the managed code is interoperating with unmanaged code and a leak exists in the unmanaged code. .NET doesn't make any guarantee that the finalizer for each object will get called. In the current implementation, .NET has one finalizer thread. If there exists a finalizer which blocks this thread, then the other finalizer will never get called and the unmanaged memory will leak which was supposed to be released. When an AppDomain is torn down, the CLR tries to run all the finalizers, but if a blocking finalizer exists, then it can prevent the CLR from completing the AppDomain tear down. To prevent this, the CLR implements a timeout on the process, after which it stops the finalization process, and the unmanaged memory which was supposed to be removed is left leaked.

Managed Heap Memory
Managed memory can also get leaked by several ways like fragmentation of the Large Object Heap. The memory in the Large Object Heap never gets compacted, so there is a loss in memory over there. Also, if there exist some objects which are not needed, but there exists a reference to the objects, then GC never claims the memory assigned to these objects.

Example:
static object someObj;

static void SomeMethod()
{
someObj = new Object();
}

The GC would not be able to collect the allocated object until someObj was set equal to null. This is because the static someObj reference is always reachable from code.

No comments:

Post a Comment