我正在处理一个内存消耗问题的应用程序。如果用户在应用程序中单击足够长的时间,则会以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释放内存,但我完全不知道是什么。
有没有人经历过类似的经历并且有任何线索?
祝你好运
岸堤
答案 0 :(得分:3)
OutOfMemoryException
有时会撒谎。有时它意味着“我无法获得一个非托管的句柄” - 它实际上并不总是 与内存有关。问题在于,通常很难说为什么某些事情会失败,而“内存不足”可能是一个合理的猜测。
听起来就像许多事情没有得到及时处理。处置它们会调用它们的自定义代码,以便主动和主动地释放它们未受损坏的句柄。
相反,GC主要是由内存压力引发的。现在,PC可以留下大量内存,但是用完了非托管句柄。答案 1 :(得分:0)
在MODEL-VIEW-VIEWMODEL (MVVM)中,如果您正在使用特殊的第三方引用,则可以将对象清除为显式控件。也许你只需要包含
object.Dispose
和object = null
答案 2 :(得分:0)
可能是很多事情
这只是一个奇怪的事情,导致我的内存不足
在set check for = value中,如果是,则返回。
查找对NotifyPropertyChanged的不必要调用
我有一个案例,我通过公共属性加载一个ObservableCollection,它正在排队多个NotifyPropertyChanged,导致内存不足。
然后我加载了私有变量,并在完成时调用NotifyPropertyChanged并修复了内存不足。