繁体   English   中英

了解内存泄漏

[英]Understanding memory leaks

我试图了解WPF内存泄漏,并且在阅读了该主题之后,我有一些不清楚的地方。

问题最好来自示例,因此让我们定义:

模型:

public class Mom : INotifyPropertyChanged
{
   public ObservableCollection<Kid> Kids { get; set; }

   private string name;
   public string Name
   {
       get => name;
       set => Set(ref name, value);
   }

   public event PropertyChangedEventHandler PropertyChanged;

   protected void Set<T>(ref T field, T newValue = default(T), [CallerMemberName] string propertyName = null)
   {
       field = newValue;
       PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
   }
}

ViewModel(DataContext)可能如下所示:

public class MomViewModel, INotifyPropertyChanged
{
   private Mom selected;
   public Mom Selected
   {
       get => selected;
       set => Set(ref selected, value);
   }
}

现在,我想问有关XAML中这两种绑定方案的问题:

第一次绑定:

<ListView ItemsSource="{Binding Selected.Kids}">
...
</ListView >

第二次绑定:

<TextBlock Text="{Binding Selected.Kids.Count}" />

现在想象一下,在ViewModel中,我们有一个计时器,它每秒分配一个新的Mom。 那就是Selected = new Mom { .. };

Q1:绑定1会产生内存泄漏吗? 该属性的类型为ObservableCollection,该类型实现INotifyPropertyChanged,但该属性本身不(仅常规获取,设置)。

Q2:绑定2会产生内存泄漏吗? 该绑定直接针对来自Collection的Count ,并且不实现INotifyPropertyChanged。

请注意,视图(XML)本身从未被破坏-每秒仅更改一次“ Selected”属性。 WPF允许进行垃圾回收(这也仅在视图被破坏或绑定发生更改时)对我来说还是不清楚的。 我的测试在这里不确定。

谢谢。

在以下示例代码中,在将Selected源属性设置为新的Mom对象之后,无论绑定到Selected.Kids还是Selected.Kids.CountMom的先前实例都可以进行垃圾回收:

public sealed class MomViewModel : INotifyPropertyChanged, IDisposable
{
    private readonly System.Timers.Timer _timer = new System.Timers.Timer();

    public MomViewModel()
    {
        _timer.Interval = 2000;
        _timer.Elapsed += (s, e) => Selected = new Mom();
        _timer.Start();
    }

    private Mom selected;
    public Mom Selected
    {
        get => selected;
        set => Set(ref selected, value);
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void Set<T>(ref T field, T newValue = default(T), [CallerMemberName] string propertyName = null)
    {
        field = newValue;
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    public void Dispose()
    {
        _timer.Dispose();
    }
}

通过在视图中设置以下绑定,不会引入任何内存泄漏:

<ListView ItemsSource="{Binding Selected.Kids}" />
<TextBlock Text="{Binding Selected.Kids.Count}" />

您所拥有的WPF特定部件均不会导致内存泄漏。

WPF绑定是弱引用,因此它们本质上不会保持活动。 如果绑定到未实现inotifypropertychanged的poco,则可能会导致内存泄漏。 你避免了。 是否筹集在二传手中更改的财产无关紧要。 因此,count也不会导致任何内存泄漏。

如果您在任何地方都遇到问题,那么看起来很有可能是如何保持对每位妈妈的参考,您正在每秒更新一次。 仍然有一些关于这些的参考,并且不允许它超出范围。 解决方法可能很简单,例如将年迈的妈妈从可观察的集合中取出并进行处理。

如果您想确切地了解阻止复杂的企业级应用程序中垃圾收集的是什么,那么可以尝试一下redgate Ants profiler。 有免费试用版。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM