WPF Application memory leak issue [duplicate] - wpf

Working with WinForms you have to free memory after using gdi objects, event handlers, objects from native code, etc.
In WinForms I used to remove for example event handlers in the dispose method.
What is the best workaround to prevent memory leaks in Wpf? Is it the same as in Winforms using Dispose pattern? At all, do I have to care about event handlers, gdi objects in Wpf? What about the runtime created resources(Brushes, etc)?

This blog post lists the most common situations that cause memory leaks in WPF applications.
Event handlers to objects in parent windows
Registering to events from static objects
Using timers
Data binding
Changing the Text property of a text box
It also describes how to fix these common issues.
Another good approach is to develop an app while following the standard guidelines and then use some kind of profiler to determine any memory leaks or performance bottlenecks.

From MSDN: Any WPF framework-level element (those objects deriving from either FrameworkElement or FrameworkContentElement) has three common lifetime events: Initialized, Loaded, and Unloaded.
.....
Unloaded is raised last and is initiated by either the presentation source or the visual parent being removed. When Unloaded is raised and handled, the element that is the event source parent (as determined by Parent property) or any given element upwards in the logical or visual trees may have already been unset, meaning that data binding, resource references, and styles may not be set to their normal or last known run-time value.

Some helpful links on WPF resource dictionary leaks:
DynamicResource\StaticResource cause memory leaks
Memory leak problem with ResourceDictionary and MergedDictionaries

Watch out for events: it's very easy to miss something, because all references from the delegate will exist until the delegate lives. I suggest to use weak event pattern when it's possible. Actually Microsoft uses it in their Prism framework.
http://msdn.microsoft.com/en-us/library/aa970850.aspx
Also check out an issue that I was catched by many times when learning WPF http://support.microsoft.com/kb/938416/en-us

Related

Why using Weak Event Pattern on controls instead of managing lifetime somewhere else?

I understand the Weak Reference and the Weak Event Pattern.
One place where the weak event pattern is used is in DataBinding between Controls and DataModel.
During the process of DataBinding, if the DataModel support INotifyPropertyChange, the Control will ask the DataModel to advise him on change through the event.
Without weak event the DataModel would have kept a hard ref on the control. Due to that reference, the control could not be marked as available for GC at the same time as the window become available to be GC.
Microsoft decided to use weak reference to solve this issue.
I wonder if other alternatives like the proposed one would not have been better ?
Alternative: Implement IDisposable on Window with code that pass its children UiElements in order to ask them to remove their DataBinding to the DataModel ?
What would have been wrong with that solution ?
There's one fundamental advantage in using weak events: the task to unbind the Control from the DataModel is left to the garbage collector itself. The garbage collector typically runs in a low-priority thread that is only activated when the system is idle or when there's need to free up memory, so it doesn't slow down other activities. By contrast, having IDisposable detach the Control from the DataModels means that if you manually dispose of the Control, the unbinding has to take place in the regular caller's thread.
Another aspect (and this is mandated by the MVC pattern) is to leave the model independent from the view. If you think of object lifetime as a dependency, weak references are exactly what it takes to keep the models independent, since you don't have to rely on the controls' cooperation to release the bindings.

Solving the memory leak issues

I have read a lot about this topic, and still I don't have the clear path how to proceed. Can anyone point to some resource (or explain) that shows in detailed step how to find the reason why some objects dctor is not called.
basically my logic for testing leak is this (WPF application):
create some View/ViewModel
close the View
call GC.Collect()
After a few seconds a dctor on ViewModel class is normally called, but on my application is never called. I would like to know which object is holding a reference to it at that time, since in my opinion it is the way to find the cause of memory leak.
This classes do not user any unmanaged resources, and do not have IDisposable implemented, which means there is no SupressFinalize call to prevent desctructor execution.
Edit: ViewModel is retrieved through a Static property on ViewModelLocator, and is added List. This is required by TabControl, which needs collection of view models to bind to. View and ViewModel are connected through DataTemplate.
First, search for non-unsubscribed event handlers and static references pointing to your ViewModel, even indirectly. Since you're in a WPF application, also ensure that you don't use DependencyPropertyDescriptor.AddValueChanged which is known to cause leaks by using static references.
If you can't find anything manually, use the awesome (this is my opinion, I'm in no way affiliated with them) SciTech .NET Memory Profiler. You can see for every object all the references it holds and which other objects are holding a reference to it, in a nice graph
view. It also warns you for common memory problems.
EDIT:
ViewModel is retrieved through a Static property on ViewModelLocator
Search no longer, you have your leak. Static references prevent objects from being garbage collected. Remove the static reference or wrap it in a WeakReference.

window closed event doesn't release memory and resource. How to solve the memory leak in WPF?

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?
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.
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
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.

Silverlight control not being garbage collected because of command

My control is being kept alive because of command it is bound to. How can I break this reference? This is causing a major memory leak in my application. The control is inside of a DataTemplate so I have no direct access to it.
Here is my ANTS memory profile:
How on earth do I break this connection?
Though I incorporated WeakEventListener, I discovered that my problem was with the control I was using to wrap up my images. I was hooking it up to DownloadProgress, ImageOpened, and ImageFailed events and never unhooked them. My thinking was that nothing else in my code was touching the BitmapImage objects so they would be garbage collected with the control. This, it sees, is not the case. The BitmapImage objects were referenced by a static member (and therefore a GC root) deep within Microsoft's code called "ManagedPeerTable.PeggedManagedPeersWithRefs". It was so deep that a Google search returned only five results for it. Now I suppose there will be six.

How built-in WPF controls manage their event handlers to an attached event?

I know that when you register an object to the mouse's attached events, you have memory leaks. That's why you need to use WeakEvent pattern.
I have a problem with this pattern : If you want to use it, you cannot define your handler in the XAML code.
To me, it means that every code like this leaks :
<SomeControl Mouse.MouseDown="MyHandler" />
Unless you remove your handler explicitly in code (And I doubt that anybody does that).
Now there is something I don't understand :
<Button Click="MyHandler" />
This code somehow use somewhere the Mouse.MouseDown event to detect a click on the button.
With some research with reflector, I found that this event use MouseDown of the UIElement class. And when I read the code of UIElement I don't understand : there is no WeakEventManager !
Can someone can explain me how UIElement recieve events from Mouse.MouseDown without leak ?
Using normal handlers in XAML does not require weak references.
What you are doing is creating a memory reference between the main control and a child control contained within this control; the child control in this case is the button.
If someone maintains a reference to any part of the visual tree for the main control, the whole tree will stay in memory because it is linked together (parent/child references).
Now if all of the references to this tree are removed, the event reference between parent and child (the main control and the button) is not significant because these controls were already linked through parent/child references. Once all external references are removed, this control can be garbage collected.
Event handlers within XAML only create internal event references.
You have to be careful when external clients register to an event on a control, because you are creating an external reference that will keep the control alive as long as the link and the client exists (unless it is a weak reference).
Your question is about attached events. There doesn't appear to be any clear documentation on whether attached events cause memory leaks. It looks to me like the UI control that subscribes to the event contains a references to the event instead of the other way around, but I assume that the static event object must have some way of notifying the control that it has been fired. There appears to be a surprising lack of comment on this from Microsoft.

Resources