Thursday, January 18, 2007

Why .Net apps consume so much memory

There are many posts out there where people ask why .Net apps consume so much memory…

I was researching a little and I found very interesting information that I'm going to comment here.

I, like every body else had a .Net 2.0 Windows application consuming a lot of memory. Initially I eliminated the possibility to minimize the application so it only could be hidden and visible again. When I saw the Task Manager (which now I know is not a good indicator or the real memory a .Net application is using) I was worry because of the high amount of memory being used. Researching I discover Windows allocates private memory (referred later as Private Bytes) and shared memory (private memory plus shared memory is referred later as Working Set) for one single application , and the shared memory can be released if the application doesn’t need it. Surprisingly when an Application is minimized Windows releases the application's shared memory making the value shown in the Task Manager very low. I tested it using some counters with the perform monitor. I added two counters for my application: Private Bytes and Working Set then Running and minimizing my App I got this output:


It shows how the Working Set drops dramatically, but Private Bytes stays flat. When I look the size of my app minimized in the Task Manager I saw it uses two or 3 MB of RAM. Wow!! Then I did the same test with Messenger and GoogleTalk and I got the same result. Windows frees memory when apps are minimized which is logic and great!

Something else I notice: When you don’t want to show your application minimized to users but still want Windows to release memory then the application’s window must be visible at the moment it is minimized for Windows to recognize the visible change.

e.g. If you hide the application and later minimized it by code like this

this.Hide();
this.WindowState = FormWindowState.Minimized;

Windows won’t recognize that it is minimized then keeping the complete memory allocated for the application (the mem value in the Task Manager does not change). The code should be like this for Windows to be aware that the application is not been used

this.WindowState = FormWindowState.Minimized;
this.Hide();


I’m going to copy here some interesting conclusion from Tim Anderson's page. (http://www.itwriting.com/dotnetmem.php)


1. Windows generally does a good job of memory management. High figures in Task Manager needn’t concern the user if the system is running well.

2. .NET applications really do have a high memory footprint relative to most native code applications (Java has the same problem).

3. Don’t use the mem usage column in Task Manager for diagnostics or profiling.

4. There isn't much developers can do about the memory footprint of the .NET runtime. However, there is a lot that developers can do to make applications that use memory efficiently and avoid leaks. This mostly involves looking at the .NET counters rather than the system counters. Use of a profiler is near-essential; I like the SciTech ( http://memprofiler.com).


2 comments:

huhushanzhi said...

Hello! You have a very nice blog! I'm here to share valuable info with you visit my my blog

el perucho said...

Realmente me parecio interesante tu articulo, cuando puedas lo traduces al español...

Lo de la traducción es broma...