I have a simple wpf application. In main window i have stack panel and 2 buttons. First button adds 100 my user controls (without any data bindings, events, bitmaps), and se
Leave the garbage collector alone and let it do its job.
What you're describing isn't a memory leak. It's dynamic memory not getting released at the moment you think it ought to be released.
Are you the garbage collector? You are not. Worrying about when garbage gets collected isn't your job. If these objects are actually garbage - and they are - the memory will be there when you need it.
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
This is a surefire way of forcing non-GCable objects into Gen2 prematurely, thus increasing your memory footprint for a longer period of time, for no good reason.
As Aliostad said: don't!
By using this Dll Invoke we can realocate the memory resources
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);
}
}
In a garbage collected environment, releasing memory immediately doesn't really make sense.
Since the CLR JITs code on demand, the first time you run your test you shouldn't see memory drop back to where it was initially. This makes sense because new code paths have been followed and code has been JITted. That code needs to reside somewhere in memory no?
Therefore, after your first test run, you shouldn't be able to collect back down to your initial memory footprint. Your baseline should be the memory usage you get after running the test once, not before. After running a second time, I am able to get memory back down to the baseline with a number of collections.
Also, I'd recommend running your project in release mode with no debugger attached. Running your program with a debugger attached will not show you a true memory profile, as there are various tricks it employs to keep objects around (e.g. Collect objects still in scope - GC.Collect).
This is all a moot point, however, because like I said above, reclaiming memory immediately doesn't make much sense in a GC environment (in most cases).
I want to release memory immediately.
Don't. Trust GC.
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
Don't. Trust GC.
After 5 - 10 min memory releases
Didn't I say trust GC?
Garbage collection model will make sure the unwanted managed memory in your system is released (which includes almost all of your controls memory). It uses an algorithm for optimising which includes generations, free memory available, possibly CPU available... so GC.Collect()
will interfere with it.
GC.Collect()
is asynchronous so no immediate effect.
The only resource you need to be careful is the unmanaged resource which usually is handled by Dispose Pattern. Otherwise don't mess with GC, it does its job very well.
I would concur with @Aliostad re GC. I does its job very well, BUT it is not a tool to magically clear all of your memory.
If you have memory leak problems, the most straightforward and reliable solution is to use a profiler, whih should be able to identify if you have a genuine leak and where it is. I have used Ants from Red Gate, but others may have better suggestions.
As well as following the usual guidelines, like making sure you properly dispose of stuff. Calling GC and hoping that it will work is not an alternative for proper code assessment.