fli*_*ubt 7 .net memory-leaks finalizer redgate winforms
我有一个WindowsForms应用程序,似乎泄漏内存,所以我使用Redgate的ANTS内存分析器来查看我怀疑的对象,并发现它们只由已经在Finalizer Queue上的对象持有.很棒,究竟什么是Finalizer Queue?你能指出我最好的定义吗?你能分享任何轶事建议吗?
此外,Finalizer Queue上的所有根GC对象都是名为"caller" 的System.Windows.Forms.Control + ThreadMethodEntry对象的实例.我看到它涉及多线程UI交互,但除此之外我不太了解.原谅我明显的懒惰并承认无知,但这些资源都埋藏在供应商的组件中.我正在和供应商讨论这些问题,但我需要一些指导才能让我加快对话速度.你能指点我最有用的ThreadMethodEntry定义吗?任何轶事建议?
另外,我是否应该关注终结器队列中的这些对象?
更新:这篇红门文章很有帮助.
Pau*_*ams 17
终结器队列包含定义了终结器方法的所有对象.回想一下,终结器是一种收集非托管资源(如句柄)的方法.当垃圾收集器收集垃圾时,它会将带有终结器的任何对象移动到终结器队列中.在某些时候 - 取决于内存压力,GC启发式和月亮的阶段 - 当垃圾收集器决定收集这些对象时,它沿着队列走下去并运行终结器.
在过去曾经处理过内存泄漏问题,在终结器队列中看到一堆供应商的对象可能是草率的代码,但它并不表示内存泄漏.通常,良好的代码将公开一个Dispose方法,该方法将收集托管和非托管资源,并且这样做会将自己从终结器队列中删除GC.SuppressFinalize().因此,如果供应商的对象确实实现了Dispose方法,并且您的代码没有调用它,那么可能会导致终结器队列中出现一堆对象.
您是否尝试过在两个时间点之间在ANTS中创建快照并比较它们之间创建的对象?这可以帮助您识别泄漏的任何托管对象.
此外,如果您想查看终结器运行时内存是否消失,请尝试使用以下内容进行测试:
System.GC.Collect(); System.GC.WaitForPendingFinalizers(); // this method may block while it runs the finalizers System.GC.Collect();
我不建议正常运行此代码.如果你刚刚做了大量的工作并且创造了大量的垃圾,你可能想要运行它.例如,在我们的应用程序中,我们的一个函数可以创建大约350 MB的垃圾,在关闭MDI窗口后会浪费掉.由于已知会留下大量垃圾,因此我们手动强制进行垃圾回收.
另请注意,基本Windows.Forms代码中有一个低级属性缓存,它将保留最后打开的模式对话框.这可能是内存泄漏的原因.摆脱此引用的一种可靠方法是强制显示另一个简单对话框,然后运行上面的GC代码.
| 归档时间: |
|
| 查看次数: |
7811 次 |
| 最近记录: |