Can Bindings Create Memory Leaks in Wpf

Can bindings create memory leaks in WPF?

If you are not binding to a DependencyProperty or a object that implements INotifyPropertyChanged then the binding can leak memory, and you will have to unbind when you are done.

This is because if the object is not a DependencyProperty or does not implement INotifyPropertyChanged then it uses the ValueChanged event via the PropertyDescriptors AddValueChanged method. This causes the CLR to create a strong reference from the PropertyDescriptor to the object and in most cases the CLR will keep a reference to the PropertyDescriptor in a global table.

Because the binding must continue to listen for changes. This behavior keeps the reference alive between the PropertyDescriptor and the object as the target remains in use. This can cause a memory leak in the object and any object to which the object refers, This includes the data-binding target.

So in short if you are binding to a DependencyProperty or INotifyPropertyChanged object then you should be ok, otherwise like any subscribed event you should unsubscribe your bindings


Edit:
There is a possibility this was fixed in .NET4.5 using Weak Events/References, But after a few quick tests it seemed the same to me, I will have to dive in more deeply to confirm, so I'll personally say in might be fixed in 4.5 :)

Why does implementing INotifyPropertyChanged avoid memory leaks in WPF?

If a property does not implement the INotifyPropertyChanged interface, then the WPF framework will stupidly add one for you by subscribing to the PropertyDescriptor.ValueChanged event. Since WPF and the CLR do not know when to dispose of / unsubscribe from the event, it holds on to the property forever. And since the property is being referenced, it can not be garbage collected. The whole instance of the class that contains that property stays in memory forever, thus causing a memory leak.

ICommand binding causing UI memory leak in WPF application

The CanExecuteChanged event handler is likely implicated in the leak.

WPF expects ICommand implementations to use weak references to the event handlers. You're using a normal .NET event which uses strong references, which can cause this leak.

The way you are creating the ParameterlessCommand instance seems to imply that CanExecute will always be true, and you don't need the event at all.
Are you actually firing the event anywhere, or is OnCanExecuteChanged unused code?

If not, replace the event definition with:

public event EventHandler CanExecuteChanged { add {} remove {} }

This way the event does not store any handlers, and the view model avoids having a strong reference to the UI elements.

If you need to raise the event, the easiest solution is to use CommandManager.RequerySuggested, which matches the weak event semantics expected for ICommand:

public event EventHandler CanExecuteChanged {
add {
CommandManager.RequerySuggested += value;
}
remove {
CommandManager.RequerySuggested -= value;
}
}

Another thing you should do is implement INotifyPropertyChanged in your view model (if you haven't done so already), and use that instead of having individual NameChanged etc. events for each property.
This is because the logic in WPF dealing with the individual properties causes memory leaks when there is a reference from the view model back to the UI elements: http://support.microsoft.com/kb/938416

AFAIK you need to implement INotifyPropertyChanged even if you don't actually have any change events.


My guess is that fixing either of these two problems will make the leak disappear: the incorrectly implemented CanExecuteChanged causes a strong reference from view model to view, which is exactly the circumstance under which the lack of INotifyPropertyChanged causes a leak.

But it's a good idea to fix both issues; not just one of them.

WPF - Is changing binding expression from one to another may cause to memory leak?

Is it possible to cause memory leak if I change the binding by trigger.

In general, there's no more potential for a leak than there would be with just a single binding. That's not to say that a leak is impossible, but if you follow the best practices and make sure anything you bind to implements INotifyPropertyChanged, then you won't accidentally cause your binding source to be retained. Binding expressions use weak references to refer to the bound object, so that won't cause a leak.

Specifically, the example you posted looks fine, and should not cause a leak.

I read somewhere (and I can't find it right now) that there are scenarios where if you give to an element the property x:Name then you may cause to memory leak.

The case would be when you remove an element with an x:Name directive from your UI tree. The reason is that x:Name doesn't just set the Name property; it also registers the element in the name scope, and that registration involves a strong reference. If you remove a named element from the UI without also removing it from the name scope, then it will be kept alive until the name scope becomes unreachable.

When removing a named element, call UnregisterName in the parent view, passing in the name of the element you are removing. That will remove it from the name scope.



Related Topics



Leave a reply



Submit