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

15

我有一个庞大的网站,似乎正在吸掉分配的所有内存。除了这个网站以外,服务器上没有其他东西。一周之内,它会耗尽2GB内存并需要重新启动。当前使用的是Server 2008 32位操作系统,使用IIS 7。我们将重新安装64位操作系统并添加更多内存。能够追踪泄漏发生的位置将非常有帮助。

那么,追踪内存泄漏的最佳实践是什么呢?


我们遇到了类似的问题,但是当我们使用大量第三方工具和自定义应用程序时,改变一切是很困难的。最好的方法是,我们设置了一个定时任务,在没有用户登录的情况下每晚进行软重启,服务器在5分钟内就能重新启动,这确实有所帮助,而不是重新编写很多东西。问题在于,并非所有开发人员都能正确编码并使用好的工具!! - Akash Kava
12个回答

15

.NET 中的内存泄漏不常见,但当它们发生时,最常见的原因是未附加事件处理程序。确保在监听器超出作用域之前分离处理程序。

另一种可能的原因是忘记在 IDisposable 资源上调用 Dispose()。这可能会阻止对未托管资源(GC 不处理的资源)的清理。

还有一个可能的原因是死锁的终结器。这将防止队列中所有剩余的对象被收集。

我使用 WinDbg + Sos 来跟踪内存泄漏。步骤如下:

  • 转储堆并查找可疑项
  • 使用 !gcroot 找出是什么使可疑项保持活动状态
  • 必要时重复此过程

请注意,大量的内存使用也可能是由于堆碎片化引起的。常规堆是紧凑的,但固定对象可能导致碎片化。此外,LOH 不是紧凑的,所以 LOH 的碎片化很常见。

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


10

4
请前往Tess Ferrandez的博客“If broken it is, fix it you should”学习如何诊断和调试与.NET代码相关的崩溃、挂起和内存问题,她提供了一些我迄今为止发现的最好的材料来帮助你入门。商业内存分析器(例如ANTSSciTech)是优秀的资源,可以显示堆中的对象及其根源。大多数商业内存分析器可以加载进程的内存“快照”(比如从你的生产环境)。
你可以使用adplus.vbs或DebugDiag捕获内存“快照”(参见Snap v. Dump)。 Adplus是Windows调试工具的一部分。 DebugDiag还将自动进行一些基本分析(但在非托管代码上似乎更可靠)。

监控应用程序
有关要监视什么的想法,请参见Improving .NET Performance and Scalability,特别是第15章。

至于如何监视,也有商业工具可用,但是,每台Windows机器也都配备了Perfmon.exe,可用于记录相关性能计数器。

测试应用程序
如果想了解如何执行负载或压力测试,请查看模式和实践Web应用程序性能测试指南

调试应用程序
一旦您确定存在问题(监控)并且能够重现问题(测试),就可以开始调试问题。请参阅Tess的链接 - 这些信息将帮助您很长一段时间。

然后反复进行! :)

祝你好运!
Z


3
在性能监视器中,添加计数器 Process/Private Bytes 和 .NET CLR Memory/# Bytes in All Heaps。Private bytes 是所有内存,而 CLR memory 只是托管的。因此,如果 CLR memory 保持相对稳定,但 private bytes 随着时间推移不断增长,这意味着泄漏出现在非托管资源中。通常这意味着您没有正确处理本机资源。值得一看的好东西是 COM 或 IO(流和文件)。确保在使用完它们后将所有这些内容都释放。

1

1

你可以尝试使用像 dotTrace 这样的分析工具 -- 将其设置为内存跟踪模式并运行你的应用程序。

这应该会给你一些线索,让你知道哪些程序集和应用程序区域在启动时占用了过多的内存。


1

这可能更多是预防而不是检测,但在 C# 代码层面上,您应该检查任何使用大量资源(如图像和其他文件)的类是否正确实现了dispose 模式。如果需要,您还可以覆盖终结器。

MSDN 对此有很好的指导。

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


1

1
EQUATEC是一个性能分析器 - 不能用于检测内存泄漏。 - Alex_P

1

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

.NET调试演示

它们可能会有所帮助。基本上,您可以使用WinDBG分析内存转储并帮助确定是什么在消耗您所有的内存。

我们使用类似的方法确定正则表达式正在消耗我们所有的内存,但仅在产品在64位机器上运行时才会出现。学习曲线有点陡峭,但WinDBG是一个非常强大的工具。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接