簡體   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