为什么从未调用.NET垃圾收集器?

时间:2013-03-11 15:49:05

标签: .net garbage-collection finalizer

我正在处理一个内存消耗问题的应用程序。如果用户在应用程序中单击足够长的时间,则会以OutOfMemoryException结束。

我使用'ANTS Memory Profiler'对应用程序进行了很长时间的分析,在我看来,没有'经典'内存泄漏(例如阻止对象被垃圾回收的事件处理程序)。

但是保留在内存中的所有对象都有一个共同点 - 它们直接或间接地使用实现Finalizer的标准.NET控件(例如TextBox,Numberbox)。在“ANTS Memory Profiler实例保留图”中,我可以看到唯一一个包含对控件引用的实例是.NET Finalizer队列。

链接保留图(我没有足够的声誉直接发布图片:-)) - > http://i50.tinypic.com/2d6r6nn.png

因此,我调查了Finalizer Thread中死锁的方向 (参见http://dotnetdebug.net/2005/06/22/blocked-finalizer-thread/) 但无法找到僵局的迹象。另外,反对死锁理论的是,在使用Memory Profiler的内存快照触发GC.Collect()之后,视图被垃圾收集 - 分别执行它们的终结器并且一切正常。

所以,这看起来像是使用Finalizer的.net对象的正常生命周期,对吧?但在我的应用程序中,我可以单击,直到OutOfMemoryException和垃圾收集器永远不会运行!

最后一个尝试处理问题的方法是使用GC.AddMemoryPressure(),因为在视图中有很多位图分配了相当多的非托管代码。但这也不能激起垃圾收集器收集空闲内存。

所以,我认为应用程序中的概念存在一些内在错误,这会阻止GC释放内存,但我完全不知道是什么。

有没有人经历过类似的经历并且有任何线索?

祝你好运

岸堤

3 个答案:

答案 0 :(得分:3)

OutOfMemoryException有时会撒谎。有时它意味着“我无法获得一个非托管的句柄” - 它实际上并不总是 与内存有关。问题在于,通常很难说为什么某些事情会失败,而“内存不足”可能是一个合理的猜测。

听起来就像许多事情没有得到及时处理。处置它们会调用它们的自定义代码,以便主动和主动地释放它们未受损坏的句柄。

相反,GC主要是由内存压力引发的。现在,PC可以留下大量内存,但是用完了非托管句柄。

答案 1 :(得分:0)

MODEL-VIEW-VIEWMODEL (MVVM)中,如果您正在使用特殊的第三方引用,则可以将对象清除为显式控件。也许你只需要包含 object.Disposeobject = null

When to dispose ViewModel in MVVM Light

答案 2 :(得分:0)

可能是很多事情

这只是一个奇怪的事情,导致我的内存不足

在set check for = value中,如果是,则返回。

查找对NotifyPropertyChanged的不必要调用 我有一个案例,我通过公共属性加载一个ObservableCollection,它正在排队多个NotifyPropertyChanged,导致内存不足。
然后我加载了私有变量,并在完成时调用NotifyPropertyChanged并修复了内存不足。