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

All*_*nek 68 .net memory-leaks crash-dumps visual-studio-2010 memory-profiling

我有一个.NET服务,其正常的私有工作集大约为80 MB.在最近的负载测试期间,进程达到3.5 GB内存使用量,导致整个机器的物理内存不足(使用4 GB中的3.9),并且在负载测试停止后很长时间内内存未释放.使用任务管理器,我获取了该进程的转储文件并在Visual Studio 2010 SP1中打开它,我可以开始调试它.

我如何诊断内存问题?我有dotTrace Memory 3.x,它是否支持转储文件的内存分析?如果没有,Visual Studio 2010 Premium的内存分析功能是否有帮助(我目前有专业版)?WinDbg可以帮忙吗?

更新:新的Visual Studio 2013 Ultimate现在可以使用转储文件本机诊断内存问题.有关详细信息,请参阅此博客文章.

wal*_*wal 122

安装WinDbg.您需要确保获得正确的x86或x64版本,具体取决于您的转储.这是x86 下载的直接链接.

在那,你需要确保你采取了正确的转储.您可以使用任务管理器创建转储文件(右键单击进程 - >创建转储文件).如果您使用64位且进程为x86,请使用32位版本的任务管理器(C:\ Windows\SysWOW64\taskmgr.exe)来获取转储文件.有关获取转储文件的更多信息,请参阅我的文章,例如,如果您使用的是XP并且需要使用windbg来创建转储文件.

警告学习曲线相当陡峭,事情可能无法完全按照这里所描述的那样工作,所以回过头来解决任何问题.

假设您可以在Visual Studio中打开转储,我假设您正在使用.NET4.这是一个非常快速的指南,可以帮助您使用dmp文件:

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

SRV*c:\symbols*http://msdl.microsoft.com/download/symbols
Run Code Online (Sandbox Code Playgroud)

2)打开崩溃转储或将.DMP文件拖到WinDbg上.

3)在命令窗口中键入此内容

.loadby sos clr
Run Code Online (Sandbox Code Playgroud)

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

4)然后键入此

!dumpheap -stat
Run Code Online (Sandbox Code Playgroud)

列出了对象的类型及其计数.看起来像这样:

在此输入图像描述

您必须在应用程序的上下文中分析它,看看是否有任何异常.

windbg 还有很多,谷歌是你的朋友.

  • 使用"!dumpheap -stat -live"来避免查看死对象. (5认同)
  • 这是一个很好的工具,可以在两个不同的内存转储之间创建一个表示增长的差异:http://thinkexception.blogspot.de/2010/06/tool-to-bompare-two-windbg-dumpheap.html (2认同)
  • 对于** dotnet core **使用命令**。loadby sos coreclr ** (2认同)

Bri*_*sen 30

通常,如果托管应用程序中存在泄漏,则表示未收集任何内容.常见的来源包括

  • 事件处理程序:如果未删除订阅者,则发布者将保留该订阅者.

  • 静力学

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

  • 类似地,死锁线程将保留它所拥有的任何根.当然,如果你有死锁的线程,可能会影响几个级别的应用程序.

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

您需要了解堆上预期的每种类型的实例数.一旦找到看起来很奇怪的东西,就可以使用该!dumpheap -mt <METHOD TABLE>命令列出给定类型的所有实例.

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

如果该实例的一切看起来都很好,那么您将转到另一个实例.如果这不会产生任何结果,您可能需要再次回头查看堆并从那里重复.

其他泄漏源包括:未卸载的组件和大对象堆的碎片.SOS/PSSCOR也可以帮助您找到这些,但我现在将跳过详细信息.

如果你想了解更多,我推荐Tess的博客.我还做了一些关于如何使用WinDbg + SOS的视频(这里这里).

如果您可以选择在运行过程中调试该过程,我建议使用PSSCOR而不是SOS.PSSCOR本质上是SOS源的私有分支,已经通过附加命令进行了增强,并且许多现有的SOS命令也得到了改进.例如,该!dumpheap命令的PSSCOR版本具有非常有用的增量列,这使得对内存泄漏的故障排除变得更加容易.

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


Ed.*_*ard 5

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