Wednesday, October 10, 2012

Memory leak

     Memory leak is something to be avoided while programming, In .NET, we have the garbage collector, I thought that the System.GC takes care of the left out objects, after going though this informative article : http://www.codeproject.com/Articles/19490/Memory-Leak-Detection-in-NET
how the GC works is ‘GC builds a list of live objects, and then walks through the heap in search of objects which are not present in this list of live objects. After finding out the objects which are not present in this list of live objects, it marks them all as garbage, and starts to compact the memory to remove holes which were created by unreferenced (dead) objects.’ So Any objects with a weak reference are cleared for Garbage collection. The steps GC goes through:

1.    Execution Engine Suspension – The EE is suspended until all managed threads have reached a point in their code execution deemed "safe".
2.    Mark – Objects that don't have roots are marked garbage.
3.    Plan – The GC creates a budget for each generation being collected, and then determines the amount of fragmentation that will exist in the managed heap as a result of a GC collection.
4.    Sweep – Deletes all objects marked for deletion.
5.    Compact – Moves all non-pinned objects that survived the GC to the lower end of the heap.
6.    Execution Engine Restart – Restart the execution of managed threads.

And Unmanaged objects cannot be reclaimed by GC, therefore a ‘finalize’ a necessary there.
Now to the point: If an object is declared using the new keyword… like let’s say
TextBox tb = new TextBox;
Then later in the code the textbox is initialized again like:
tb = (TextBox)Page.FindControl(“TextBox1”);
then does this mean there is a leak?
So I used the GC.GetTotalMemory method to check what happens
Not this may not be the right way to get the memory used. Many in these forum Posts argue that it’s not possible to get the memory used during runtime.
The below console application calculates the memory used before and after a DataTable Object is created, And also if the DataTable is newed again.

namespace memTest
{
    class Program
    {
        static void Main(string[] args)
        {
            long mem = 0;
            mem = GC.GetTotalMemory(true);
            Console.WriteLine(mem.ToString());
            DataTable dt = new DataTable();
            mem = GC.GetTotalMemory(true);
            Console.WriteLine("After Datatabled is newed"+mem.ToString());
            dt = new DataTable();
            mem = GC.GetTotalMemory(true);
            Console.WriteLine("After Datatabled is newed again" + mem.ToString());
            Console.Read();
        }
    }
}

This is the output I got:



 105752 Is at the start, After the DataTable is created It becomes 109960 and after the same DataTable is 'newed' again, the memory remains the same.
And therefore does this mean that the garbage collector recognizes and manages the memory re-allocation?

Your comments please