为了追踪内存泄漏,我一直在使用Visual Studio和SOS.dll来提供对象堆的转储,并查看GCR射击特定对象的内容。
我开始使用AutoIt自动执行此过程来控制我的鼠标和键盘。这是我脚本第一部分的近似值:
但是,我对我目前的方法有些担忧。我不仅依赖于安装Visual Studio,而且在脚本运行时,我不能使用鼠标或键盘而不会使自动化失序。在Visual Studio中,按F5开始执行
让程序完全加载
切换到Visual Studio并中断执行将焦点切换到即时窗口
加载SOS.dll
致电!dumpheap -stat
将转储结果复制到剪贴板
粘贴在记事本中并保存为dump1.txt恢复执行
多次执行泄漏动作
切换到Visual Studio并中断执行将焦点切换到即时窗口
清除输出
致电!dumpheap -stat
将转储结果复制到剪贴板
粘贴到记事本中并保存为dump2.txt运行Python脚本,比较两个转储并找到泄漏的对象
有没有办法在C#程序而不是Visual Studio中使用SOS.dll?理想情况下,此解决方案将附加到指定的进程并将!dumpheap -stat
的结果输出到文本文件,而无需自动化Visual Studio。
答案 0 :(得分:9)
下面我将介绍一些可用于查找泄漏的不同方法。
(如果您不想遵循DIY方法,那么有商业"泄漏"探测器可用)。
您实际上并不需要Visual Studio来使用SOS.DLL ....它是一个调试器扩展,因此也可以在WinDBG中使用。
您可以免费获得WinDBG调试器作为Windows调试工具的一部分。
然后,您可以编写一个WinDBG脚本来自动执行"转储"。
另外请注意,SOS.DLL的增强版本可用...寻找SOSEX,PSSCOR2(针对NET 2)和PSSCOR4(针对NET 4)。
您可以使用CLR Profiling API。
有一个名为CLRProfiler的应用程序,它是一个实际的.NET分析器,可以使用它....所以有很多代码可以看看它是如何使用的。
CLR Profiler可以做的事情之一是允许进行堆转储,然后比较在不同时间段进行的转储,找出差异......从而帮助发现泄漏。
您可以在"测试"中为您的应用程序提供类似的功能。模式(嵌入在应用程序中,或作为监视它的配套实用程序)。
您可以使用的另一种技术是定期"转储"您的进程,然后您可以使用SOS / SOSEX(或任何其他WinDBG插件)通过WinDBG离线分析。
您可以使用DebugDiag(您可以设置规则和操作来控制何时创建.dmp文件)以自动创建.dmp文件....或者一个名为ProcDump.exe的工具(来自SysInternals)。
http://www.microsoft.com/en-us/download/details.aspx?id=26798
http://technet.microsoft.com/en-us/sysinternals/dd996900.aspx
ProcDump特别有用,因为它能够拍摄"过程快照"非常快,因为它使用了一种名为" Process Reflection" ....的技术,这使得您的过程可以不那么积极地中断,例如。
(创建3个转储,每个转储间隔5秒)
procdump -s 5 -n 3 notepad.exe notepad.dmp
拥有一组.dmp文件后,您可以分析它们以查找泄漏,监控句柄使用情况等。
你可以在WinDBG中手动加载.dmp文件,然后发出调试器命令,或者你可以编写一个WinDBG扩展或者一个脚本,它接受转储文件集并依次处理它们(即运行!dumpheap stat命令他们)。
这是一个旨在分析.dmp文件和进行事后分析的工具。
它允许您在.NET中编写脚本,因此可能比WinDBG更容易访问。
如果你想扩展它,它还有一个插件模型。
它允许您编写/使用展示台以独特的方式查看数据。
(目前仅支持CLR 2.0内存转储......不支持CLR 4.0)