【问题标题】:How to debug .net Garbage Collection?如何调试.net 垃圾收集?
【发布时间】:2009-02-17 14:35:01
【问题描述】:

是否可以查看调用 GC.Collect() 时收集的所有 .net 对象?

我需要查看哪些对象仍在内存中并且没有被回收,所以我可以找到应该手动回收对象但被程序员忘记的地方。
我不想调用 GC.Collect,因为某个地方的某个人忘记处置一个阻塞了一些句柄的对象。

【问题讨论】:

  • "should have [collected]" 是 GC 的一个奇怪短语
  • 我经常听到人们这么说!开发人员说“它超出了范围,为什么不收集它?”假设 GC 会自动完成一切。虽然这是一部了不起的作品,但它并不完美。对 GC 了解得越多,就越知道一不小心就会发生内存泄漏。
  • "should have ..." 不是指 GC,而是手动处理对象 - 抱歉混淆了语言使用!
  • FxCop 可以帮助确定代码是否忽略给定类型的 IDisposable。

标签: .net debugging garbage-collection


【解决方案1】:

我发现最好的方法是使用 windbg 和 SOS(罢工之子)扩展。它有一个相当神秘的命令行,但它非常强大。它具有转储堆并将其除以 GC 分代堆的能力。一旦你通过了最初的学习曲线,就很容易在堆的哪个部分跟踪哪些对象是活动的。以下是一些使用 SOS 示例的网站

EDIT OP 询问 sos.dll 的位置。它包含在 .Net Framework 的安装中。它位于

%WINDIR%\Microsoft.Net\Framework\V2.0.50727\sos.dll

但是一旦你加载了windbg,你就不需要完整的路径了。只需要我们的 .loadby 方法。

.loadby sos mscorwks.dll

它将在与当前版本的 mscorwks(CLR)相同的目录中查找 sos 的版本

【讨论】:

  • 我无法加载 sos.dll - 这不适用于托管(混合)c++ 吗?
  • 只要加载了 CLR,它就应该适用于任何托管代码。尝试使用 .load 和完整路径 tho sos.dll。
  • 我试过了,我得到:'调用 LoadLibrary(C:\Windows\Microsoft.NET\Framework\v2.0.50727\SOS.DLL) 失败,Win32 错误 0n193'
  • CLR 应该被加载。我在程序后期中断,windbg 告诉我它已经加载了很多 .net-dll,例如:'ModLoad: 71fb0000 72540000 C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorwks.dll'跨度>
  • @Sam,你在 64 位机器上吗?如果是这样,请使用 framework64 版本 C:\Windows\Microsoft.NET\Framework64\v2.0.50727\SOS.DLL
【解决方案2】:

我使用SciTech's Memory profiler。立即使用有点复杂,但是有一些很好的教学视频。它会让您查看哪些对象没有正确处理,它们是在哪一代收集的。没有它就无法调试内存泄漏...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-16
    • 1970-01-01
    • 2010-10-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多