如何检测内存泄漏的位置?

时间:2009-09-23 02:44:52

标签: c# .net memory-leaks

我有一个大型网站似乎正在吸收正在分配的所有内存。此站点旁边的服务器上没有其他任何内容。在一周内,它会吃掉2场演出并需要重新启动。目前这是使用IIS 7的服务器2008 32位。我们重新安装使用64位并添加更多内存。能够追踪泄漏发生的位置会很好。

那么跟踪内存泄漏的最佳做法是什么?

12 个答案:

答案 0 :(得分:14)

.NET中的内存泄漏并不常见,但是当它们发生时,最常见的原因是未连接的事件处理程序。在侦听器超出范围之前,请确保分离处理程序。

另一种选择是忘记在Dispose()资源上致电IDisposable。这可能会阻止清理非托管资源(不由GC处理)。

另一个可能的原因是一个僵局的终结者。这将阻止收集终结器队列中的所有剩余对象。

我使用WinDbg + Sos来追踪泄漏。步骤如下

  • 转储堆并寻找嫌疑人
  • 使用!gcroot找出让嫌犯活着的原因
  • 根据需要重复

请注意,大量内存使用也可能是由于堆碎片造成的。常规堆是压缩的,但固定的对象可能会导致碎片。此外,LOH没有压实,所以LOH并不罕见。

关于WinDbg + sos的优秀教程:http://blogs.msdn.com/tess/

答案 1 :(得分:9)

在您的代码上运行探查器。

以下是两个不错的选择:

RedGate's memory profiler

Jetbrains dotTrace

我相信这两种产品都有免费试用。

答案 2 :(得分:4)

  

跑步,不要走路,走到苔丝身边   Ferrandez的博客If broken it is, fix it you should,很好   专门用于学习的脚本实验室   如何诊断和调试崩溃,挂起   和.NET代码的内存问题。她   有一些我最好的材料   迄今为止找到了帮助你入门。

商业内存分析器(例如ANTSSciTech)是极好的资源,可以显示堆中的对象以及它们的根源。大多数商业内存分析器都能够加载进程的内存“快照”(例如,从您的生产环境中)。

您可以使用adplus.vbs或Snap v. Dump捕获内存“快照”(请参阅​​DebugDiag)。 Adplus作为Debugging Tools for Windows的一部分提供。 DebugDiag还将自动进行一些基本的分析(但在非托管代码上似乎更可靠)。

监控应用
有关监控内容​​的想法,请参阅Improving .NET Performance and Scalability,特别是第15章。

关于如何监控,也有可用的商业工具,但是,每台Windows机器都附带Perfmon.exe,可用于记录相关的性能计数器。

测试应用
有关如何执行负载或压力测试的想法,请查看模式和实践Performance Testing Guidance for Web Applications

调试应用程序
一旦你发现你遇到问题(监控)并且能够重现问题(测试),你就可以开始调试问题。查看苔丝的链接 - 这些信息将为您带来很长的路要走。

然后冲洗并重复! :)

祝你好运!
ž

答案 3 :(得分:3)

在性能监视器中,为所有堆中的进程/专用字节和.NET CLR内存/#字节添加计数器。专用字节是所有内存,CLR内存只是管理。因此,如果CLR内存保持相当均匀,但私有字节会随着时间的推移而持续增长,这意味着泄漏位于非托管资源中。这通常意味着您没有正确处理本机资源。好看的是COM或IO(流和文件)之类的东西。完成后,确保所有这些东西都被处理掉了。

答案 4 :(得分:1)

您可以尝试使用dotTrace等分析器 - 将其设置为内存跟踪并运行您的应用程序。

这应该可以为您提供线索,其中应用程序的程序集和区域在开始时会占用太多内存。

答案 5 :(得分:1)

这可能是预防而不是检测,但在c#代码级别,您应该检查使用大型资源(如图像和其他文件)的任何类是否正确实现the dispose pattern。如果需要,您可能还需要覆盖终结器。

MSDN对此主题有很好的指导。

如果您的应用程序中有任何您知道使用大量资源的类,那么这些是第一个查找内存问题的地方。

答案 6 :(得分:1)

我发现EQATEC Profiler非常好,而且它是免费的!

答案 7 :(得分:1)

在此博客文章中查看内存和内存泄漏实验:

.NET Debugging Demos

他们可能会有所帮助。基本上,您可以使用WinDBG来分析内存转储,并帮助确定占用所有内存的内容。

我们使用类似的方法来确定Regex正在咀嚼我们所有的内存,但只有当产品在64位计算机上运行时才会这样。学习曲线有点陡峭,但WinDBG是一个非常强大的工具。

答案 8 :(得分:1)

答案 9 :(得分:0)

你做任何Office互操作吗?如果是这样,请确保清理应用程序对象。这是一个可能的罪魁祸首。

另一个是全局对象,例如任何静态的对象。

答案 10 :(得分:0)

您的网站上有很多动态网页吗?

您还可以尝试IBM's Purify

我建议您尝试使用一小组动态页面,同时禁用所有其他页面。我讨厌这样说,但IIS 7很可能也有漏洞。

答案 11 :(得分:0)

查看页面底部提到的this article on detecting .NET application memory leaks及相关文章,希望您能找到解决方案,或者至少有一个想法来解决它。

由于