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!

25 comments:

  1. 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.

    ReplyDelete
  2. Thank you very much, this post is very useful.

    ReplyDelete
  3. 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

    ReplyDelete
  4. 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.

    ReplyDelete
  5. 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

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

    ReplyDelete
  7. Anonymous8:48 AM

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

    ReplyDelete
  8. This comment has been removed by the author.

    ReplyDelete
  9. This comment has been removed by the author.

    ReplyDelete
  10. 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!

    ReplyDelete
  11. This comment has been removed by a blog administrator.

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

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

    ReplyDelete
  14. Hola muchas gracias.
    Hello thanks

    From Colombia!!!

    ReplyDelete
  15. Hola muchas gracias.
    Hello thanks

    From Colombia!!!

    ReplyDelete
  16. Great post. Help a lot...
    Thanks...

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

    ReplyDelete
  18. 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

    ReplyDelete
  19. This comment has been removed by the author.

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

    ReplyDelete
  21. 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 ????

    ReplyDelete
  22. 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

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

    ReplyDelete
  24. 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

    ReplyDelete
  25. 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..

    ReplyDelete