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

.net 如何使用转储文件诊断内存泄漏?,.net,visual-studio-2010,memory-leaks,crash-dumps,memory-profiling,.net,Visual Studio 2010,Memory Leaks,Crash Dumps,Memory Profiling,我有一个.NET服务,正常的私有工作集大约为80MB。在最近的一次负载测试中,进程的内存使用率达到3.5 GB,导致整个机器的物理内存不足(使用了4 GB中的3.9 GB),并且在负载测试停止后很长时间内存没有释放。使用任务管理器,我获取了一个进程的转储文件,并在VisualStudio2010SP1中打开了它,我可以开始对它进行调试 如何诊断内存问题?我有dotTrace Memory 3.x可供使用,它支持转储文件上的内存分析吗?如果没有,VisualStudio2010 Premium的内

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

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

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

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


dotTrace可以生成可视内存图表(比WinDbg更好),但决不要将其用于转储。

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

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

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

我假设您正在使用.NET4,因为您可以在VisualStudio中打开转储。以下是帮助您使用dmp文件的快速指南:

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

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

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

.loadby sos clr
(仅供参考,对于.NET 2,命令应为
.loadby sos mscorwks

4) 然后打这个

!dumpheap -stat
其中列出了对象的类型及其计数。 看起来像这样:

您必须在应用程序的上下文中对此进行分析,并查看是否有任何异常


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

一般来说,如果你的托管应用程序出现漏洞,就意味着没有收集到某些东西。共同来源包括

  • 事件处理程序:如果未删除订阅服务器,则发布服务器将保留它

  • 静力学

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

  • 类似地,死锁线程将保留它所保留的任何根。当然,如果您有死锁线程,可能会在多个级别上影响应用程序

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

您需要了解堆上每种类型的实例数量。一旦你发现一些奇怪的东西,你可以使用
!dumpheap-mt
命令列出给定类型的所有实例

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

如果该实例的所有情况看起来都很好,则转到另一个实例。如果这并没有产生任何结果,您可能需要再次返回查看堆并从那里重复

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

如果你想知道更多,我推荐你。我还制作了两个视频,介绍了如何使用WinDbg+SOS(和)

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


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

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

非常有趣的指南。那些P&P公司的家伙们确实出了很多好东西。不过只有Visual Studio 2013终极版…@Samuel:真的吗?多么令人伤心和失望……这是引用的msdn文章:。它指出,选择的先决条件是最终的。确实令人失望,因为我认为它在RC1中可用,并已被推到了Ultimate,这是一个相当昂贵的功能,然后…根据下面的答案,您可能还需要额外的步骤来加载Windows SOS/CLR DLL。我解决了这个问题,并在这里添加了一个快速的步骤摘要:这是一个很好的工具,可以在两个不同的内存转储之间创建差异,指示增长:使用“!dumpheap-stat-live”来
!dumpheap -stat