Reputation: 97
Recently I noticed serious memory leak in my WPF project. If simplify the project, it has a login form and a main form. In main form there are 1 user control which is composed of about 30 user controls and 3 buttons, 1 user control which has 3 buttons and a Infragistics datagrid. I use background worker to query DB every 30 sec only for the datagrid.
After I logout of the main form using main form.closed and re-launch the login window, I noticed that every time there is 6-7MB increase measured by ANTS memory profiler 7. Even though I have unregistered event handlers, set variables to null and called GC.Collect(), memeory leak is still the same. My questions are: 1. Why close wpf window doesn't release the memory and resource? I can see many strings(most of them are from GUI) are still in memory after close window by ANTs profiler. 2. Do I need to unregister the events defined by resource event setter? Do I need to unregister the events declared in XAML? 3. From WPF memory leak, people said we should not use GC.Collect(), but I do see a little improvement. Shall we use it or not?
Upvotes: 0
Views: 2645
Reputation: 41
I have had a simillar problem while using WindowsFormsHost for PictureBox control. The WPF window using WF PictureBox control could not be fully released and that's why i had a regular ~10mb increase everytime i re-opened the subwindow. The problem was solved since i started nulling the WFH object on WPF window closing. Just make sure You clear all the WF controls if You use such.
Upvotes: 3
Reputation: 2323
It depends. User controls in WPF do not inherently dispose, so you will have to override the functionality and allow it in your controls with:
http://msdn.microsoft.com/en-us/library/system.idisposable.dispose.aspx
But to your point, you will need to do a GC.Collect() at least once as SlimGG suggests.
In most cases, calling the garbage collector directly is considered bad practice because it is not calling it for your control specifically, but for all objects queued for disposal.
Upvotes: 0
Reputation: 3201
Break into the debugger and then type this into the Immediate window:
.load C:\Windows\Microsoft.NET\Framework\v2.0.50727\sos.dll
The path to sos.dll varies. The way to find out the correct path is to look for mscorwks.dll in the Modules pane. Wherever that is loaded from is the correct path for sos.dll.
Then type this:
System.GC.Collect()
That will ensure anything not reachable is collected. Then type this:
!DumpHeap -type <some-type-name>
This will show you a table of all existing instances, with addresses. You can find out what is keeping an instance alive like this:
!gcroot <some-address>
originally answered by Daniel
Upvotes: 0