Подтвердить что ты не робот

Могут ли привязки создавать утечки памяти в WPF?

Нужно ли отключать элементы, поскольку элемент исчезает, чтобы предотвратить утечку памяти? Наверное, я немного обеспокоен тем, что если я перезагрузился, и новый шаблон будет применен к элементу управления, и в этом шаблоне существует привязка к внешнему элементу, может ли это предотвратить блокирование элемента управления для сбора мусора?

4b9b3361

Ответ 1

Если вы не привязываетесь к DependencyProperty или объекту, который реализует INotifyPropertyChanged, тогда привязка может утечка памяти, и вам придется отменить привязку, когда вы закончите.

Это связано с тем, что если объект не является DependencyProperty или не реализует INotifyPropertyChanged, то он использует событие ValueChanged с помощью метода PropertyDescriptors AddValueChanged. Это приводит к тому, что CLR создает сильную ссылку от PropertyDescriptor до object, и в большинстве случаев CLR будет хранить ссылку на PropertyDescriptor в глобальной таблице.

Поскольку привязка должна продолжать прослушивать изменения. Это поведение сохраняет ссылку между PropertyDescriptor и object, поскольку цель остается в использовании. Это может привести к утечке памяти в object и любом object, к которому относится object. Это включает в себя цель привязки данных.

Итак, если вы привязываетесь к объекту DependencyProperty или INotifyPropertyChanged, тогда вы должны быть в порядке, в противном случае, как и любое подписанное событие, вы должны отказаться от подписки на свои привязки


Edit: Возможно, это было исправлено в .NET4.5 с использованием слабых событий/ссылок, но после нескольких быстрых тестов мне показалось одинаковым, мне придется глубже погрузиться в подтверждение, поэтому я лично скажу в может фиксироваться в 4.5:)

Ответ 2

Из http://msdn.microsoft.com/en-us/library/aa970850.aspx WPF использует шаблоны слабых событий, которые не содержат сильных ссылок на объекты и позволяют им быть GC'ed if они являются единственными ссылками на объект.

"Многие аспекты привязки данных WPF уже имеют шаблон слабых событий, применяемый в том, как реализуются события."

Ответ 3

Не претендуйте на ответ, просто для справки. В классической статье на Finding Memory Leaks in WPF-based applications автор Jossef Goldberg подробно описал случаи, когда в приложении WPF может быть утечка памяти. На самом деле, большинство относятся к .NET 3.5/4.0, но некоторые случаи могут иметь отношение к этому дню. Кроме того, есть небольшое расширение .

Цитата о утечке в Binding:

Cause:

Эта утечка зафиксирована в этой статье kb. Он запускается, потому что:

Элемент управления TextBlock имеет привязку к объекту (myGrid), который ссылается на TextBlock (это один из дочерних объектов myGrid).

Note:, что этот тип утечки DataBinding уникален для конкретного сценария (а не для всех сценариев DataBinding), как описано в статье kb. Свойство в Path не является a DependencyProperty, а не классом, реализующим INotifyPropertyChanged, и, кроме того, должна существовать цепочка сильных почтений.

код:

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

В XAML также может быть записан тот же самый код утечки:

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

Fix/Workaround:

Существует несколько подходов, самый простой - просто очистить привязку, когда окна уже закрываются.

например:.

BindingOperations.ClearBinding(MyTextBlock, TextBlock.TextProperty);

Другой подход - установить режим привязки данных к OneTime. См. Статью kb для других идей.

Полезная ссылка:

Избегайте утечки памяти WPF с помощью DataBinding