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

我有一个正常的私人工作集大约80 MB的.NET服务。 在最近的负载testing期间,进程达到了3.5 GB的内存使用量,导致整个机器在物理内存上很低(使用4 GB的3.9 GB),并且在负载testing停止后很久没有释放内存。 使用任务pipe理器,我拿了一个进程的转储文件,并在Visual Studio 2010 SP1中打开它,我可以开始debugging它。

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

更新:新的Visual Studio 2013旗舰版现在可以使用转储文件本机诊断内存问题。 看到这个博客文章的更多细节。

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

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

警告有一个相当陡峭的学习曲线,事情可能无法完全按照此处所述的方式工作,所以回到任何问题。

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

1)运行WinDbg,设置符号path(File – > Symbol Search Path)为

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

2)打开崩溃转储或拖动您的.DMP文件到WinDbg。

3)在命令窗口中input

 .loadby sos clr 

(FYI,对于.NET 2,命令应该是.loadby sos mscorwks

4)然后input这个

 !dumpheap -stat 

其中列出了对象的types和数量。 看起来像这样:

在这里输入图像说明

你将不得不在你的应用程序的上下文中分析,看看是否有什么exception。

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

一般来说,如果您在托pipe应用程序中发生泄漏,则意味着某些内容未被收集。 常见的来源包括

  • 事件处理程序:如果用户没有被删除,发布者将会保留它。

  • 静力学

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

  • 同样,一个死锁的线程将保持它所拥有的任何根。 当然,如果你有死锁的线程,可能会影响在几个层面上的应用程序。

为了解决这个问题,你需要检查托pipe堆。 WinDbg + SOS(或PSSCOR)会让你这样做。 !dumpheap -stat命令列出了整个托pipe堆。

您需要了解堆中预期的每种types的实例数量。 一旦发现看起来很奇怪的东西,可以使用!dumpheap -mt <METHOD TABLE>命令列出给定types的所有实例。

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

如果一切看起来都很好,那么就转到另一个实例。 如果没有产生任何东西,你可能需要回头再看堆,然后重复。

其他泄漏源包括:未卸载的组件和大对象堆的碎片。 SOS / PSSCOR可以帮助你find这些,但是现在我将跳过细节。

如果你想知道更多,我推荐苔丝的博客 。 我也做了一些video,介绍如何使用WinDbg + SOS( 这里和这里 )。

如果您可以在运行时debugging进程,则build议使用PSSCOR而不是SOS。 PSSCOR实质上是SOS资源的一个专用分支,已经增加了额外的命令,现有的许多SOS命令也得到了改进。 例如, !dumpheap命令的PSSCOR版本有一个非常有用的增量列,这使得更容易排除内存泄漏。

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

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

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

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