I\'ve been profiling a WinForm\'s application using \".NET Memory Profiler\".
I can\'t quite seem to understand how my application is growing to 1GB, then 2GB, then
I can't quite seem to understand how my application is growing to 1GB, then 2GB, then 3GB of usage - according to windows task manager.
That's because the counter from task manager is the "working set" as Tess Ferrandez points out in this article
There is another counter called working set which simplified consists of how much memory is in the memory pages that are currently or was recently touched by threads in the process or approximately, how much of the memory that is used by the process is currently in RAM. The working set counter might be interesting if you have issues with too much paging and many processes on the same box competing about the RAM, but in order to determine how much memory you are using (reserved or committed) it offers little or no help.
From the MSDN article on working set (Emphasis mine)
Working Set
The set of memory pages (areas of memory allocated to a process) recently used by the threads in a process. If available memory on the server is above a specified threshold, pages remain in the Working Set of a process even if they are not in use. When available memory falls below a specified threshold, pages are removed from the Working Set. If these pages are needed, they will be returned back to the Working Set before they leave main memory and are made available for other processes to use.
I have found that under high CPU load that the garbage collection often gets a very low priority so the .NET libraries responsible for cleaning up unused memory will only fire off when they absolutely have to, in spite of the reference counts to a managed object going to zero. If it's possible try putting some intentional Thread.Sleep calls in your code or simply accept the fact that it's a memory hog and hope that the logic will allow your system to run and it will have "odd" memory usage as you never stated that anything breaks, it just has an unreal memory footprint.
Is this a known issue for VB.NET apps?
Yes. It is a side-effect of Edit + Continue support compiled into the executable. It is affected by any event that is declared with the WithEvents keyword. A WeakReference keeps track of those event instances. Problem is, those WeakReferences are leaked if you run the app without a debugger. The rate at which the process consumes memory is highly dependent on how many instances of the class get created. The leak is 16 bytes per event per object.
The workaround is simple, do not use the Debug build of your app without a debugger. Only use the Release build. And of course, only ship the Release build to your customer.