Google Analytics

Search This Blog

Wednesday, March 25, 2015

VB.NET Memory Leak Case Study

In this example, we explore a case study of memory leak simulated by VB.NET

First of all, the code would generate a persistent memory surge.

Then, it explores methods to clear the memory surge effectively without leak.

Eventually, it attempts to simulate memory leak based on the same model.

Refer to the sample code (VB.NET Visual Studio 2008 SP1).

Running the code, the program starts with a base of around 4,500 K memory (private working set).




Make use of 'Performance Monitor' to see what happens to these memory.


From Run, type 'Perfmon'.

From the Performance Monitor, under 'Monitor Tools', click 'Performance Monitor'.



Select '.NET CLR Memory', select the exe from from the sample code, click 'Add'.



Select 'Histogram Bar'.



Click 'Generate Memory', immediately, the memory surge to around 36,000 K.




Go back to 'Performance Monitor', you can see that the action brings up many bars.



Pay attention to the bright blue bar which is '# Bytes in all Heaps'.

Now, click 'Clear Memory 1'.




The private working set immediately drops to around 7,000 K.

And if you compare the starting base memory of 4,500 K with 7,000 K after clearing the memory, does this means that there are around 3,500 K of memory leak ?

To confirm what are these additional 3,500 K memory, go back to 'Performance Monitor'.



It shows what is left are:
  • Process ID
  • Gen 0 heap size
  • Finalization Survivors
  • # GC Handles
  • # Total reserved Bytes

To understand what are all these, check out the following url.

https://msdn.microsoft.com/en-us/library/x2tyfybc%28v=vs.110%29.aspx

Hence, eventually, it is understood that what is left are actually two things:
  • # GC Handles
  • # Total reserved Bytes

# GC handlers:

Displays the current number of garbage collection handles in use. Garbage collection handles are handles to resources external to the common language runtime and the managed environment.


# Total reserved bytes:

Displays the amount of virtual memory, in bytes, currently reserved by the garbage collector. Reserved memory is the virtual memory space reserved for the application when no disk or main memory pages have been used.


Hence, since these two resources are mandatory to the working of garbage collection, therefore, the remainders of the elevated bytes are not due to leaked bytes - in order words there is no memory leak here.

Simulate Memory Leak:

Now, let's perform the 'Generate Memory' again.

This time, instead of clearing memory, click either one of memory leak methods: 'Memory Leak 1', 'Memory Leak 2'.

After which, pay attention that the memory maintains around 23,000 K.




Pay attention to Performance Monitor, the # Bytes in all heaps was maintained at a high level compared to the scenario when memory is properly cleared.


If you keep performing 'Garbage Collection' by clicking on 'Garbage Collection', the memory utilization doesn't drop.

To clear memory effectively, it is as simple as four things - really.

1.) Implement the IDisposable interface for each class and invoke the dispose method whenever an object is no longer needed.

This is the best practice, but is not the one and only method.

https://msdn.microsoft.com/en-us/library/hks5e2k6.aspx

2.) After invocation of disposed method, set the variable to nothing.

Take note that setting object reference to nothing is more important than invocation of dispose method - which essentially is about invocation of GC.SuppressFinalize.

3.) Invoke gc.collect.

If you do not invoke gc.collect explicitly, garbage collector will happen only when the threshold is reached.

https://msdn.microsoft.com/en-us/library/ee787088%28v=vs.110%29.aspx#conditions_for_a_garbage_collection

4.) Remember to clear objects from data structure such as array, collection and etc.

This is the most commonly ignored overlooked.

Refer to the source code (VB.NET Visual Studio 2008 SP1).

No comments: