.NET内存泄漏 - System.WeakReference对象累积

时间:2012-10-08 13:13:40

标签: .net vb.net memory-leaks windbg sos

我有一个用VB.NET编写的服务泄漏了内存。即使它没有做太多,内存也会增长。它开始在任务管理器中使用大约29,000 K,并且经过几个小时后,根据它的繁忙程度,它会增长到500,000K或有时超过1,000,000K。对于某些客户,这会导致其服务器出现内存问题。该服务具有自动重启功能,每天重启一次服务,但有时这还不够,我们需要每天多次使用Windows调度程序的net stop / start。

PerfMon显示“Gen 2堆大小”在serivce运行时继续增长,而其他堆数则没有。当然,“所有堆中的#字节”也会增长,因为它包含了这个数字。

当我创建正在运行的服务的转储文件时,在windbg中打开它,加载SOS,并在其上运行“!dumpheap -stat”,最大数量的对象属于“System.WeakReference”类。在我现在看的例子中,总共4,636,227个对象中有4,542,785个。

根据我的阅读,GC使用这些对象来保存对其正在使用的对象的引用,这是如何出现的?如果是这样的话,那么为什么它们也不会用GC来完成它们呢?有没有办法看到WeakReference对象持有什么对象?

谢谢!

2 个答案:

答案 0 :(得分:2)

WeakReference将保留对对象的弱引用,但对WeakReference - 实例的引用很难,因此:如果你持有大量死亡(IsAlive是{ {1}})引用它们仍将使用内存。

确保您不将false存储在列表中,或将其存储在其他方面以供永久使用。

修改: 如果您没有自己持有引用,可能是由issues with WithEvents in VB.NET引起的。简而言之,在发布模式下编译您的应用程序,问题应该修复according to Microsoft.

答案 1 :(得分:0)

似乎代码中WeakReference类的使用无效。 要定位代码,构建实例,使用一些分析工具,可以从分配点跟踪整个对象的生命周期(例如dotTrace Memory)。 有人忘了清理某些集合中的Dead弱引用实例。 查找并修复。