Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can bindings create memory leaks in WPF?

Do I need to unbind items as the item disappears in order to prevent memory leaks? I guess I'm just a little worried that if I reload and a new template is applied to a control, and in that template there exists a binding to an outside element, could that prevent the control made for the template from being garbage collected?

like image 791
James Joshua Street Avatar asked Aug 30 '13 23:08

James Joshua Street


People also ask

What is the main cause of memory leaks?

A memory leak starts when a program requests a chunk of memory from the operating system for itself and its data. As a program operates, it sometimes needs more memory and makes an additional request.

What does binding DO WPF?

Data binding is a mechanism in WPF applications that provides a simple and easy way for Windows Runtime apps to display and interact with data. In this mechanism, the management of data is entirely separated from the way data. Data binding allows the flow of data between UI elements and data object on user interface.

How do we avoid memory leaks in closures?

Only capture variables as unowned when you can be sure they will be in memory whenever the closure is run, not just because you don't want to work with an optional self . This will help you prevent memory leaks in Swift closures, leading to better app performance.


2 Answers

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 :)

like image 189
sa_ddam213 Avatar answered Oct 05 '22 20:10

sa_ddam213


Not pretend to answer, just for reference. In a classic article on Finding Memory Leaks in WPF-based applications author Jossef Goldberg, described in detail cases, where there may be a memory leak in WPF application. Really, most relate to the .NET 3.5/4.0, but some cases may be relevant to this day. Also, have a small extension.

Quote about leak in Binding:

Cause:

This leak documented in this kb article. It is triggered because:

The TextBlock control has a binding to an object (myGrid) that has a reference back to the TextBlock (it is one of myGrid children’s).

Note: that this type of a DataBinding leak is unique to a specific scenario (and not to all DataBinding scenarios) as documented in the kb article. The property in the Path is a not a DependencyProperty and not on a class which implements INotifyPropertyChanged and in addition a chain of strong references must exist.

Code:

myDataBinding = new Binding("Children.Count"); myDataBinding.Source = myGrid;  myDataBinding.Mode = BindingMode.OneWay; MyTextBlock.SetBinding(TextBlock.TextProperty, myDataBinding); 

Same leaky code can be also written in XAML:

<TextBlock Name="MyTextBlock"             Text="{Binding ElementName=myGrid, Path=Children.Count}" /> 

Fix/Workaround:

There are few of approaches, the easiest one is simply to clear the binding when the windows is about to close.

e.g.:

BindingOperations.ClearBinding(MyTextBlock, TextBlock.TextProperty); 

Other approach is to set the mode of the data binding to OneTime. See the kb article for other ideas.

Useful link:

Avoiding a WPF memory leak with DataBinding

like image 41
Anatoliy Nikolaev Avatar answered Oct 05 '22 18:10

Anatoliy Nikolaev