我一直在研究如何避免由于视图模型对INotifyCollectionChanged事件的强引用而导致的内存泄漏。我一直在尝试使用ListCollectionView,看看它是否能帮我解决这个问题。我认为下面是内存泄漏,我是不是做错了什么?
var stuff = new ObservableCollection<string>();
while (true)
{
var result = new ListCollectionView(stuff);
// Just to keep make sure that the memory I'm seeing
// isn't waiting to be GC'd
GC.Collect();
}发布于 2015-11-25 00:09:40
ListCollectionView的文档不是很好,但是如果您注意到有一个方法DetachFromSourceCollection。此调用的备注提到了取消订阅和允许垃圾收集。
var stuff = new ObservableCollection<string>();
while (true)
{
ListCollectionView result = new ListCollectionView(stuff);
//Use this method to unsubscribe to events on the underlying collection and allow the CollectionView to be garbage collected.
result.DetachFromSourceCollection();
//When finished set to null
result = null;
GC.Collect();
}发布于 2011-04-22 04:32:44
我最初发表这篇文章是作为一个评论,但我认为这是一个更好的答案,所以...
a)如果您确定发现了.NET框架的问题,那么您可能做错了什么。这不是不可能的,只是不太可能。b) GC.Collect()不会像你想的那样工作。
我认为你需要回顾一下GC.Collect()是如何工作的。
MSDN GC.Collect Method
备注
使用此方法可以尝试回收所有无法访问的内存。
所有对象,无论它们在内存中存在了多长时间,都被认为是要收集的;但是,在托管代码中引用的对象不会被收集。使用此方法强制系统尝试回收最大可用内存量。
对于初学者来说,你没有告诉我们你在哪里处理ListCollectionView(stuff)的内存。你只是分配新的和分配新的,但你永远不会处理旧的。所以,是的,它会像疯了一样泄露出去。直到GC运行并尝试收集。
如果您使用字符串列表执行与此处演示相同的操作,则它很可能会执行相同的操作。但对于你所展示的,我希望它会泄露出去。
发布于 2011-04-22 04:45:26
当您调用GC.Collect时,您的变量result仍然在作用域中,因此它不会被收集,因为只有一个指向数据的指针。不管怎样,即使不是这样。就应用程序代码而言,垃圾收集所做的工作是不确定的。就像drachenstern说的那样,它只会试一试!它最终会成功,但你不能确定什么时候会成功!
https://stackoverflow.com/questions/5749403
复制相似问题