【问题标题】:ObservableCollection not garbage collected unless it is manually set to nullObservableCollection 除非手动设置为 null,否则不会被垃圾收集
【发布时间】:2017-03-13 07:44:14
【问题描述】:

在 WPF 应用程序中,我有一个 XAML 窗口,它打开另一个窗口并将其 DataContext 设置为 ViewModel 类的实例。除此之外,视图中的 ListView 绑定到 ViewModel 中的 ObservableCollection。

ViewModel 在初始化时会加载大约 7,000 个项目,ListView 会显示它们(在 VirtualizedStackPanel 中)。

在 VS2015 的调试性能监视器中,我注意到在关闭第二个窗口后,(据我所知)没有更多对包含 7,000 个项目的 ViewModel 的引用,这些项目仍然存在于内存中。它们在第 0 代、第 1 代和第 2 代的几次垃圾收集中存活下来(并且它们不在 LOH 中)。

经过长时间的调查,我发现当窗口关闭时将 7,000 个项目的 entier 集合设置为 null,并确保引发 OnPropertyChanged 事件,会导致该项目集合立即被收集。试图在 VS 堆快照工具中跟踪此集合的根源是不可能的,因为它们被认为与一堆 XAML 控件和元素相关联。

我的问题是:这是正常行为吗?你必须一直清空我的对象吗?我可能会错过什么?

【问题讨论】:

  • “第二个窗口关闭后的那个”——到底是怎么回事?
  • 从窗口的关闭按钮关闭。 XAML 的代码背后有 Closed 和 Closing 事件的方法,它们都调用 ViewModel 来清理一些对象。
  • 您是否尝试将 DataContext 设置为 null?
  • 并非如此。我是不是该?如果窗口超出范围并且它是唯一引用 ViewModel 的对象,我为什么要这样做?
  • 来自其自己的 XAML 文件的引用是正常且无害的。但一定要调查手柄还会发生什么。如果您需要此网站的更多帮助,请联系minimal reproducible example

标签: c# wpf xaml mvvm garbage-collection


【解决方案1】:

最可能的原因是您在第二个 XAML 窗口视图中做了某事,该视图以非弱方式订阅了 ViewModel 上的事件。您不必担心 Windows 完成的 View-to-VM 订阅,因为这些订阅在默认情况下很弱,因此它们不会泄漏。我会首先查找您编写的可能订阅 VM 事件的行为,例如 ObservableCollection.CollectionChangedICommand.CanExecuteChanged

【讨论】:

    猜你喜欢
    • 2011-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-19
    • 2014-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多