【问题标题】:.NET memory leak - System.WeakReference objects accumulate.NET 内存泄漏 - System.WeakReference 对象累积
【发布时间】:2012-09-28 18:00:34
【问题描述】:

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

PerfMon 显示“第 2 代堆大小”在服务运行时继续增长,而其他堆数则不会。当然,“# Bytes in all heaps”也会增长,因为它包含了这个数字。

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

根据我的阅读,GC 使用这些对象来保存对它正在使用的对象的引用,这是这样的吗?如果是这样,为什么在处理完它们后它也不会 GC 呢?有没有办法查看 WeakReference 对象持有的对象是什么?

谢谢!

【问题讨论】:

  • WeakReference 类有一个 Target 属性来保存被引用的对象。您的服务是否经常使用WeakReference
  • 不,我们根本不声明它。据我所知,GC 在其处理中使用了这些。
  • WeakReference 由 System.Web.Caching 在框架中的其他类中使用。你能检查一下 WeakReference 的根源是什么?

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


【解决方案1】:

WeakReference 将持有对对象的弱引用,但对 WeakReference-instance 的引用很难,因此:如果您持有很多死的(IsAlivefalse)引用,它们将仍然使用内存。

确保不要将WeakReferences 存储在列表中或以其他方式永久存储它们。

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

【讨论】:

  • 澄清一下,我没有将任何东西声明为弱引用。据我所知,GC 在其处理中使用了这些。
  • 对 WeakReference 对象的样本运行 !sos.gcroot。您还可以运行 !sosex.bhi 来构建索引,然后对 WeakReference 对象的样本运行 !mroot。
  • 我确实使用 WithEvents,所以听起来可能与此有关。但是,在上面的链接答案中,这意味着发布版本不会有泄漏,但似乎该服务上的所有内容都是作为发布版本构建的。还有什么要寻找的,可能会阻止 WithEvents 这样做吗?
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2015-05-12
    • 2011-03-22
    • 2012-10-31
    • 2012-02-19
    • 1970-01-01
    • 2022-12-06
    • 2011-04-25
    • 2012-09-12
    相关资源
    最近更新 更多