[Message Deleted]
-
Actually I have seen this with non-.NET programs as well. When an app gets minimized Windows can swap out memory that is not needed and free things up. I just did this with Word and it went down to 1-2M when minimized and then back up to about 5M when it is brought back up front. Another app that we run here at work went from 18M while it was running, down to 1-2M when minimized and then back up to 6M when it was opened again. This definately is not anything to do with .NET itself.
Steve Maier, MCSD MCAD MCTS
-
On minimize, two things happen. THe first is that the framework releases most of the extra memory it's allocated from the OS to cover against future requests. Since form initialization uses alot more memory than is needed during runtime, apps that don't substantially increase the ammount of data in ram after loading the form tend to have a large amount of extra availabl. The amount held is determined by the framework, and is partially dependent on how much the system has available. The reason for de/allocating in large chunks rather than small ones is that getting memory from the OS is a costly operation. A system wide memory shortage will cause the OS to send 'return extra memory' messages and do the same thing. The second is that most of the app is moved from system to virtual memory. On restore, the code is only moved out of VM on an as needed basis.
-
The 'Mem Usage' column in Task Manager is actually the current working set size. The working set is the set of physical memory pages which the OS thinks are currently necessary to run the program. Periodically, about once a second, a thread in the OS called the balance set manager wakes up and trims (removes) pages from each working set on the system, to ensure that there are always enough free physical pages of memory to satisfy demand. There is also an upper limit of working set size for each process, which is defaulted to about 1.5MB, but this is really an advisory limit - if there are enough free pages, this number is ignored. You can set your process's limits with the
SetProcessWorkingSetSize
function, but there's no benefit in doing so. When the USER subsystem minimizes a window, it automatically asks the operating system to trim the process's working set, since the assumption is that you aren't going to be using it again straight away. You can get the same effect by callingSetProcessWorkingSetSize
, passing -1 for both minimum and maximum working set size parameters. Pages are added to the working set by allocating them, or, after they've been trimmed, by accessing them. If your program has good locality of reference, the working set will normally stay quite low. To see how much load you're putting on both physical memory and the page file, enable the VM Size column. This is equivalent to the Process: Private Bytes counter in the Performance tool (in Administrative Tools). The .NET Framework manages all your allocations from a set of virtual memory allocations. The garbage collector generally just moves data around within the existing allocations, until its newest generation becomes full, at which point it will ask the OS for a new block (referred to as a segment). If it does have a completely free segment after performing a collection, it may return it to the OS - this is the only way that the VM Size column will go down. To keep the size of the GC heap down, ensure that you're getting rid of your objects promptly. If an object implements theIDisposable
interface, or otherwise offers aClose
orDispose
method, you must call it when you're finished with the object. If you don't, when the GC runs (and the object has a finalizer) it will go onto a queue (called freachable) for the finalizer thread to run the finalizer. The memory will only be released back to the GC heap when the GC -
The responses by Dan and Mike are absolutely correct. You also should not rely on GC.Collect, as it interferes with the natural GC collection schedule, which can actually hurt your application performance. The GC runs on its own thread and actually freezes your applications main thread while it is running. Instead of calling GC.Collect when the child form is closed, you really should be calling the Dispose method of the form. In addition to the blog mentioned, you can check http://www.codeproject.com/useritems/idisposable.asp[^] for an explanation on how to implement the Dispose pattern.