如何使用转储文件诊断内存泄漏?

我有一个。NET 服务,其正常私有工作集约为80MB。在最近的一次负载测试中,进程达到了3.5 GB 的内存使用量,导致整个计算机的物理内存不足(使用了4 GB 中的3.9 GB) ,并且在负载测试停止后很长时间内内存都没有释放。通过使用任务管理器,我获取了该进程的转储文件,并在 VisualStudio2010SP1中打开它,然后就可以开始对其进行调试。

我该如何诊断记忆问题?我可以使用 dotTrace Memory 3.x,它支持转储文件的内存分析吗?如果没有,VisualStudio2010Premium 的内存分析特性是否有所帮助(我目前使用的是 Professional) ?WinDbg 能帮忙吗?

更新: 新的 VisualStudio2013终极版现在可以使用转储文件自动诊断内存问题。

59815 次浏览

Http://msdn.microsoft.com/en-us/library/ee817660.aspx

微软在这里有一个指南,但是对于初学者来说太难了。

DotTrace 可以生成可视化内存图表(比 WinDbg 更好) ,但是从来不用它进行转储。

安装 WinDbg。您需要确保根据转储获得正确的 x86或 x64版本。下面是到 x86的 下载的直接链接。

在这一点上,你需要确保你采取了正确的转储。您可以使用 Task Manager 创建转储文件(右键单击 process-> Create Dump File)。 如果处于64位,进程为 x86,则使用32位版本的 Task Manager (C: Windows SysWOW64 taskmgr.exe)获取转储文件。有关获取转储文件的更多信息,请参见 我的文章,例如,如果您使用 XP,并需要使用 windbg 来创建转储文件。

警告 有一个相当陡峭的学习曲线,事情可能不会完全按照这里描述的那样工作,所以请带着任何问题返回。

我猜你在吸毒。考虑到 NET4,您可以在 VisualStudio 中打开转储。这里有一个 非常快速指南来帮助你处理 dmp 文件:

1)运行 WinDbg,将符号路径(文件-> 符号搜索路径)设置为

SRV*c:\symbols*http://msdl.microsoft.com/download/symbols

2)打开 Crash dump 或将.DMP 文件拖到 WinDbg 上。

3)在命令窗口中输入

.loadby sos clr

(仅供参考,对于.NET 2,命令应该是 .loadby sos mscorwks)

4)然后输入这个

!dumpheap -stat

它列出了对象的类型和它们的计数。 看起来像这样:

enter image description here

您必须在应用程序的上下文中分析这一点,看看是否有什么不寻常的地方。

很多更多的风吹,谷歌是你的朋友。

通常,如果托管应用程序中存在泄漏,则意味着没有收集到某些内容。常见来源包括

  • 事件处理程序: 如果没有删除订阅者,发布者将保留它。

  • 静电干扰

  • 终结器: 阻塞的终结器将阻止终结器线程运行任何其他终结器,从而阻止收集这些实例。

  • 类似地,死锁线程将持有它所持有的任何根。当然,如果您有死锁线程,这可能会在几个层次上影响应用程序。

要解决这个问题,您需要检查托管堆。WinDbg + SOS (或 PSSCOR)将允许您这样做。!dumpheap -stat命令列出整个托管堆。

你需要知道堆上每种类型的数量。一旦您发现某些东西看起来很奇怪,您可以使用 !dumpheap -mt <METHOD TABLE>命令来列出给定类型的所有实例。

下一步是分析这些实例的根。随机选一个,然后做 !gcroot。这将显示特定实例是如何根化的。查找事件处理程序和固定对象(通常表示静态引用)。如果您看到终结器队列在那里,您需要检查终结器线程正在做什么。为此使用 !threads!clrstack命令。

如果那个实例看起来一切正常,那么您就转移到另一个实例。如果这没有产生任何结果,那么您可能需要再次查看堆,并从那里重复操作。

其他泄漏源包括: 未卸载的程序集和大型对象堆的碎片。SOS/PSSCOR 也可以帮助你找到这些信息,但是我现在跳过这些细节。

如果你想知道更多,我推荐 泰丝的博客。我还制作了一些视频介绍如何使用 WinDbg + SOS (给你给你)。

如果您可以选择在流程运行时调试流程,我建议使用 PSSCOR而不是 SOS。PSSCOR 本质上是 SOS 源的一个私有分支,它通过附加命令得到了增强,许多现有的 SOS 命令也得到了改进。例如,!dumpheap命令的 PSSCOR 版本有一个非常有用的 delta 列,这使得解决内存泄漏问题更加容易。

为了使用它,您需要启动您的进程,附加 WinDbg 并加载 PSSCOR 和做一个 !dumpheap -stat。然后让进程再次运行,以便进行分配。中断执行并重复命令。现在 PSSCOR 将显示自上次检查以来添加/删除的数量。

自2017.2版本以来,JetBrains dotMemory 以其强大的功能和奇特的 GUI 支持 Windows 内存转储分析。