Post

.NET Application Memory Flush via Interop

Holy crap!!! My application is taking up too much memory and it’s just a default form?  What is going on here?

Well, this is actually normal with an application utilizing the .NET Framework.  Many things are happening when you launch your application such as code access security, JIT compilation, memory management and the referencing of the actual .NET Framework library(ies).  However, if you are really concerned with the amount of memory your application is reporting you can try the following to give your application and Windows a kick in the rear to more accurately report the current memory usage of your application. This tip is purely for cosmetic purposes, to help calm those irritating phone calls asking why your application uses more memory than Microsoft Word does… and it’s just a Hello World application.  There is no performance gain of any kind from using this tip.  See warnings below for additional information.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Public Class MemoryManagement
  
  Private Declare Function SetProcessWorkingSetSize Lib "kernel32.dll" ( _
    ByVal process As IntPtr, _
    ByVal minimumWorkingSetSize As Integer, _
    ByVal maximumWorkingSetSize As Integer) As Integer

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

End Class

This will force a garbage collection to occur and if running on Windows NT, 2000, XP, or 2003, will (according to the SDK documentation):

The working set of a process is the set of memory pages currently visible to the process in physical RAM memory. These pages are resident and available for an application to use without triggering a page fault. The minimum and maximum working set sizes affect the virtual memory paging behavior of a process.

The working set of the specified process can be emptied by specifying the value -1 for both the minimum and maximum working set sizes.

Using a simple windows application as a test, add a command button, within the click event call upon the FlushMemory method, you will see the application go from using nearly 15meg of memory usage to around 1meg (or less).

Warning:  This nice little method doesn’t come without a cost.  Don’t call upon this method during critical sections of your code.  Forcing a garbage collection can be very time consuming.  Also, don’t try to set the minimum and maximum sizes; let .NET’s memory management do it’s job.

A couple of more references (or more accurately opinions) for you to read if you intend on using GC.Collect: Chris Brumme - ReleaseComObject and Rico Mariani - Two things to avoid for better memory usage

Thanks to Jeff Berg for the tip, I just converted it to VB.NET and gave a little bit more of an explanation of what’s actually occurring.

Also, this tip will work for any type of .NET application running on a version of Windows other than Windows 9x versions.

This post is licensed under CC BY 4.0 by the author.