.net 如何使用转储文件来诊断内存泄漏?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9514401/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I use a dump file to diagnose a memory leak?
提问by Allon Guralnek
I have a .NET service with a normal private working set of about 80 MB. During a recent load test, the process reached 3.5 GB memory usage causing the whole machine to be low on physical memory (3.9 of 4 GB used), and the memory was not released long after the load test was stopped. Using task manager, I took a dump file of the process and opened it in Visual Studio 2010 SP1, and I am able to start debugging on it.
我有一个 .NET 服务,它有一个大约 80 MB 的普通私有工作集。在最近的一次负载测试中,进程达到了 3.5 GB 的内存使用率,导致整个机器的物理内存不足(使用了 4 GB 中的 3.9 个),并且在负载测试停止后很久没有释放内存。使用任务管理器,我获取了进程的转储文件并在 Visual Studio 2010 SP1 中打开它,然后我就可以开始调试了。
How do I diagnose the memory issue? I have dotTrace Memory 3.x at my disposal, does it support memory profiling on dump files? If not, will the memory profiling features of Visual Studio 2010 Premium help (I currently have Professional)? Can WinDbg help?
如何诊断内存问题?我可以使用 dotTrace Memory 3.x,它是否支持对转储文件进行内存分析?如果没有,Visual Studio 2010 Premium 的内存分析功能是否有帮助(我目前拥有 Professional)?WinDbg 可以帮忙吗?
UPDATE:The new Visual Studio 2013 Ultimatecan now natively diagnose memory issues using dump files. See this blog postfor more details.
更新:新的Visual Studio 2013 Ultimate现在可以使用转储文件本地诊断内存问题。有关更多详细信息,请参阅此博客文章。
回答by wal
Install WinDbg. You need to make sure you get the correct version x86 or x64 depending on your dump. Here is a direct link to the downloadfor x86.
安装 WinDbg。您需要确保根据您的转储获得正确的 x86 或 x64 版本。这是x86下载的直接链接。
On that, you need to ensure you took the correct dump. You can use Task Manager to create the dump file (right click on process -> Create Dump File). If you're on 64bit and your process is x86 use the 32bit version of Task Manager (C:\Windows\SysWOW64\taskmgr.exe) to take the dump file. See my articlefor more info on taking dump files, eg if you're on XP and need to use windbg to create the dump file.
在这方面,您需要确保进行了正确的转储。您可以使用任务管理器创建转储文件(右键单击进程 -> 创建转储文件)。如果您使用的是 64 位并且您的进程是 x86,请使用 32 位版本的任务管理器 (C:\Windows\SysWOW64\taskmgr.exe) 来获取转储文件。有关获取转储文件的更多信息,请参阅我的文章,例如,如果您使用的是 XP 并且需要使用 windbg 创建转储文件。
warningthere's a fairly steep learning curve and things might not work exactly as described here so come back with any issues.
警告有一个相当陡峭的学习曲线,事情可能不像这里描述的那样工作,所以有任何问题回来。
I'm assuming you're using .NET4 given you can open the dump in Visual Studio. Here's a veryquick guide to help you work with your dmp file:
我假设您使用的是 .NET4,因为您可以在 Visual Studio 中打开转储。这是一个非常快速的指南,可帮助您处理 dmp 文件:
1) Run WinDbg, set symbols path (File -> Symbol Search Path) to
1)运行WinDbg,将符号路径(文件->符号搜索路径)设置为
SRV*c:\symbols*http://msdl.microsoft.com/download/symbols
2) Open Crash dump or drag your .DMP file onto WinDbg.
2) 打开崩溃转储或将您的 .DMP 文件拖到 WinDbg 上。
3)type this into the command window
3)在命令窗口中输入
.loadby sos clr
(FYI, for .NET 2, the command should be .loadby sos mscorwks)
(仅供参考,对于 .NET 2,命令应该是.loadby sos mscorwks)
4) then type this
4)然后输入这个
!dumpheap -stat
which lists the type of objects and their count. looks something like this:
它列出了对象的类型及其计数。看起来像这样:


You will have to analyze this in the context of your application and see if anything appears unusual.
您必须在应用程序的上下文中对此进行分析,并查看是否有任何异常。
There is muchmore to windbg, google is your friend.
Windbg还有很多,谷歌是你的朋友。
回答by Brian Rasmussen
Generally if you have a leak in a managed application, it means that something is not getting collected. Common sources include
通常,如果托管应用程序中存在泄漏,则意味着未收集某些内容。常见的来源包括
Events handlers: If the subscriber is not removed the publisher will hold on to it.
Statics
Finalizers: A blocked finalizer will prevent the finalizer thread from running any other finalizers and thus prevent these instances from being collected.
Similarly, a deadlocked thread will hold on to whatever roots it holds. Of course if you have deadlocked threads that will probably affect the application on several levels.
事件处理程序:如果订阅者没有被移除,发布者将保留它。
静力学
终结器:阻塞的终结器将阻止终结器线程运行任何其他终结器,从而阻止收集这些实例。
类似地,死锁线程将保留它持有的任何根。当然,如果您有死锁线程,这可能会在多个级别上影响应用程序。
To troubleshoot this you need to inspect the managed heap. WinDbg + SOS (or PSSCOR) will let you do this. The !dumpheap -statcommand lists the entire managed heap.
要解决此问题,您需要检查托管堆。WinDbg + SOS(或 PSSCOR)会让你做到这一点。该!dumpheap -stat命令列出了整个托管堆。
You need to have an idea of the number of instances of each type to expect on the heap. Once you find something that looks odd you can use the !dumpheap -mt <METHOD TABLE>command to list all instances of a given type.
您需要了解堆上预期的每种类型的实例数。一旦发现看起来很奇怪的东西,您可以使用该!dumpheap -mt <METHOD TABLE>命令列出给定类型的所有实例。
The next step is to analyze the root of these instances. Pick one at random and do a !gcrooton that. That will show how that particular instance is rooted. Look for event handlers and pinned objects (usually represent static references). If you see the finalizer queue in there you need to examine what the finalizer thread is doing. Use the !threadsand !clrstackcommands for that.
下一步是分析这些实例的根。随机选择一个,然后做一个!gcroot。这将显示该特定实例是如何生根的。寻找事件处理程序和固定对象(通常代表静态引用)。如果您在那里看到终结器队列,则需要检查终结器线程在做什么。为此使用!threads和!clrstack命令。
If everything looks fine for that instance you move on to another instance. If that doesn't yield anything you may need to go back to look at the heap again and repeat from there.
如果该实例一切正常,您将转到另一个实例。如果这没有产生任何结果,您可能需要返回再次查看堆并从那里重复。
Other sources of leaks include: Assemblies that are not unloaded and fragmentation of the Large Object Heap. SOS/PSSCOR can help you locate these as well, but I'll skip the details for now.
其他泄漏源包括: 未卸载的程序集和大对象堆的碎片。SOS/PSSCOR 也可以帮助您找到这些,但我现在将跳过详细信息。
If you want to know more I recommend Tess' blog. I've also done a couple of videos covering how to use WinDbg + SOS (hereand here).
如果你想了解更多,我推荐Tess 的博客。我还制作了一些介绍如何使用 WinDbg + SOS 的视频(此处和此处)。
If you have the option of debugging the process while it runs, I recommend using PSSCORinstead of SOS. PSSCOR is essentially a private branch of the SOS sources that has been enhanced with additional commands and many of the existing SOS commands have been improved as well. E.g. the PSSCOR version of the !dumpheapcommand has a very useful delta column, which makes troubleshooting memory leaks much easier.
如果您可以选择在进程运行时对其进行调试,我建议使用PSSCOR而不是 SOS。PSSCOR 本质上是 SOS 源的一个私有分支,它通过附加命令得到了增强,许多现有的 SOS 命令也得到了改进。例如,!dumpheap命令的 PSSCOR 版本有一个非常有用的 delta 列,这使得对内存泄漏进行故障排除变得更加容易。
In order to use it you need to start your process, attach WinDbg and load PSSCOR and do a !dumpheap -stat. Then you let the process run again so allocations are made. Break the execution and repeat the command. Now PSSCOR will show you the number of instances that were added/removed since the previous inspection.
为了使用它,您需要启动您的进程,附加 WinDbg 并加载 PSSCOR 并执行!dumpheap -stat. 然后让进程再次运行,以便进行分配。中断执行并重复命令。现在 PSSCOR 将显示自上次检查以来添加/删除的实例数。
回答by Ed.ward
Since version 2017.2 JetBrains dotMemory supports Windows memory dumps analysis with all its power and fancy GUI.
自 2017.2 版以来,JetBrains dotMemory 以其强大的功能和精美的 GUI 支持 Windows 内存转储分析。
回答by Lex Li
http://msdn.microsoft.com/en-us/library/ee817660.aspx
http://msdn.microsoft.com/en-us/library/ee817660.aspx
Microsoft has a guide here. However, it is too tough for beginners.
微软在这里有一个指南。但是,对于初学者来说太难了。
dotTrace can generate visual memory charts (better than WinDbg), but never use it for dumps.
dotTrace 可以生成可视内存图表(比 WinDbg 更好),但从不将其用于转储。

