Thursday, February 07, 2008

Release memory in Windows Form application using C#

Windows Form applications (Microsoft.Net Desktop applications) sometimes start consuming a lot of memory, which has different drawbacks, but I'll not get into the details of them here. What we'll look into is how to avoid the excess use of the memory resource in a windows application in C#.

In fact, you need to flush memory to release all the unused memory to make more space available for your current and other applications. First of all include following two namespaces:

using Microsoft.Win32;
using System.Runtime.InteropServices;

and then use the following code snippet to flush excesssive use of memory. You can view the currently consumed memory by viewing the application process name in the currently running processes list. For that purpose just go to the Task Manager, and then go to Processes tab and find out your application's process.

Following code imports a win32 dll and flushes the memory. But, before that it also uses Microsoft.Net's garbage collector to force an immidiate garbage collection:

public class MemoryManagement
{
[DllImportAttribute("kernel32.dll", EntryPoint = "SetProcessWorkingSetSize", ExactSpelling = true, CharSet =
CharSet.Ansi, SetLastError = true)]

private static extern int SetProcessWorkingSetSize(IntPtr process, int minimumWorkingSetSize, int
maximumWorkingSetSize);

public static void FlushMemory()
{
GC.Collect();
GC.WaitForPendingFinalizers();
if (Environment.OSVersion.Platform == PlatformID.Win32NT) { SetProcessWorkingSetSize(System.Diagnostics.Process.GetCurrentProcess().Handle, -1, -1);
}
}

copy and use this class in your code and have fun reducing the memory size!

26 comments:

Unknown said...

Thanks a Bunch. I was trying to figure this out. I gave up after a bit and found your Post. Works like a charm. I am dynamically, building Items and re-adding them and the Garbage collector did't seem to keep up.

Unknown said...

Thank you very much, this post is very useful.

tomas lund petersen said...

This is awesame. my aplication used to weigth around 30MB by the task manager and now it weigth's arround 5MB with peaks of 20 something. this is to be a distributed application and the amount of memory consumed was crippling. Thanks a lot

Unknown said...

Thanks a lot!!!!

Your magic code worked great on worker processes!!!

My application used to take 1+GB RAM cause of some complex binary data conversion. With this code, I can think implementing threading gracefully.

San said...

Brilliant Man.. Just don't know how to thank you. This works just great.. I had to import half a million documents and was thinking how is my code going to work..? is the memory leaking somewhere or what. But this is cool.. But I still don't know how it works. How is .Net garbage collector not able to free memory that this code does. --Sandeep

gustavo.bonilla said...

This is a good one...... good post....

San said...

this reduces the memory usage but the VM Size still keeps growing..

Alex Vorn said...

hi! how about visual basic net? What codes can I use in VB net?

Ajit Chahal said...
This comment has been removed by the author.
Ajit Chahal said...
This comment has been removed by the author.
dshakya said...

Thank you so so much. This really helped me flush the huge memory being used by my application while loading up aerial photographs.

You are a genius.. no doubt!

Ajit Chahal said...
This comment has been removed by a blog administrator.
Tofan Nayak said...

it's awesame, thank u very much.
really u r talented

Unknown said...

i don't have words to thank you.....
Thank you very much :)

ChEch.0 said...

Hola muchas gracias.
Hello thanks

From Colombia!!!

ChEch.0 said...

Hola muchas gracias.
Hello thanks

From Colombia!!!

Unknown said...

Great post. Help a lot...
Thanks...

Unknown said...

thank you...so much. work for me. 200 mb reduces to 8 mb.

M.A Bakar said...

Perfect !!!

VB.net code :

Public Class MemoryManagement

_
Private Shared Function SetProcessWorkingSetSize(process As IntPtr, minimumWorkingSetSize As Integer, maximumWorkingSetSize As Integer) As Integer
End Function

Public Sub FlushMemory()
GC.Collect()
GC.WaitForPendingFinalizers()
If Environment.OSVersion.Platform = PlatformID.Win32NT Then
SetProcessWorkingSetSize(System.Diagnostics.Process.GetCurrentProcess().Handle, -1, -1)
End If
End Sub

End Class

M.A Bakar said...
This comment has been removed by the author.
M.A Bakar said...

Vb.net : <System.Runtime.InteropServices.DllImport("kernel32.dll" ..
Private Shared Function SetProcessWorkingSetSize( ...

Unknown said...

Can any one suggest me how to use above code in Silverlight Application. because iam not able to system.Diagnostics.Process refeence.
Pls help me .

I want to fix memory leak issue by using above code .DOes it supports in silverlight ????

Sayyad Mohd Hasan said...

Wonderful, Really this came out me from a big problem, my app was using a lot of memory and printing was failed many times but due to this code wow!!!! its working fine
Thanks a lot live long

Unknown said...

Where shall i write this code in my windows application? in which form?

kanika said...

Don't Know How to Thanks U Bro but one thing i say if i can't read ur post my job almost gone
Great work its like magic

Unknown said...

woww! work amazing, Thanks man...you probably a genius.

but i don't understand something, according to the task manger my app taks amount of around 25,000kb of memory(private working set), and when i use this FlushMemory(), it drops down to 1000kb - 2000kb, but still all the resources (Pictureboxs, Bitmaps, Variables) i use in the app are still exists and accessible like nothing happened...

how this is possible?, i expect them to be disposed/deleteded from the memory..