ASP.NET中如何检测内存泄漏

30

我们开发团队目前正在使用 ASP.NET 3.5/4.0,并且我们的网站正在运行 IIS 7.5。最近,我们遇到了问题(大约每周一次),导致 ASP.NET 应用程序抛出内存不足异常。所谓“解决方案”是重启我们网站上的应用程序池。我说“解决方案”,因为它几乎不是一种解决方案;这只是一个简单地让我们的应用程序池保持在合理状态的临时措施。似乎有些应用程序或许多应用程序正在泄漏内存,随着时间的推移,导致内存不足异常。虽然我可以设置 IIS 定期重新启动应用程序池,但我更想知道如何检测内存泄漏,以尝试修复程序,而不是继续敷衍了事。是否有任何工具可以可能检测和记录 ASP.NET 应用程序的内存泄漏?

此外,当我们开始使用 Telerik 的 RAD 控件时,我们真正开始看到更多这样的问题。是否有其他人使用这些控件时也遇到类似的问题?

谢谢,

Aaron


1
你的应用程序是否调用了任何非托管代码?如果是,我建议从那里开始查找。 - Chris Shouts
2
这个问题不应该被关闭。它问了一个简单的问题:“是否有任何工具可以可能检测和记录ASP.NET应用程序的内存泄漏?”这绝对是一个有效的问题,可以在SO格式内回答。 - Daniel P
5个回答

38

我之前在回答另一个问题时发布了这个指南,但那个问题和我的回答似乎已被删除。以下是具体步骤:

  1. 在服务器上安装Windows SDK(可作为Windows SDK的一部分)中的调试工具。
  2. 当应用程序运行一段时间后,使用adplus捕获进程的内存转储(最好使用诸如Process Explorer之类的工具来查找正确的进程ID进行转储):

    ADPLUS -hang -p <process id> -o .

  3. 这将创建一个包含内存转储的目录。现在可以使用windbg打开转储文件(文件->打开崩溃转储...)

  4. 现在出现了不受控制的代码。但你可以使用称为Son of Strike的工具来查看.NET代码,以查看已分配哪些对象。首先要加载SOS:

    .loadby sos mscorwks

然后让它检查托管堆:

!dumpheap -stat

通常情况下,这会输出大量的信息,但是有两列显示按类型消耗的实例数量和内存量。有些类型你会经常看到(例如String),但是如果有数千个自定义类型的实例,那么你可能会在某些地方泄漏这些对象。我曾经遇到过的一个问题是,在对象中将事件处理程序钩住静态应用程序中的事件——然后该事件对每个对象都有一个活动引用。

我永远不记得大多数操作的工作原理,通常会参考这个SOS秘籍表

Tess Ferrandez有一个很好的博客,有时候会介绍使用非托管调试器进行.NET调试的方法


例如,去年五月份的一篇文章详细介绍了如果使用带有非默认构造函数的XmlSerializer可能会出现的问题。


谢谢!我最终使用了这种方法。它确实指引了我正确的方向。 - Aaron
1
非常感谢,这对我帮助很大。同时,对于任何和我一样的人,我必须使用这两个答案¹ ²才能获取内存。 - talles

5

有很多内存分析工具可供选择。

其中一款热门工具是DotTrace,另一款是ANTS memory profiler,两者都是商业软件。


DotTrace是用于性能的,但同一页上有链接到dotmemory,它非常有帮助,可以检测内存泄漏。 - hima
ANTS分析器易于使用,在Red-Gate网站上有一个很好的指南,不仅清楚地解释了如何使用它,而且还包含了许多有用的信息。我和另一位开发人员在几年前成功地将其应用于一个大型Web表单项目中。 - RobC

1
你也可以尝试使用asp.net Web Profiler。它是一个免费的工具,允许您在应用程序运行时查看存储在内存中的信息。
这样可以分析asp.net缓存,查看所有当前会话和应用程序状态的内容。

1

1

ASP中的.Net内存泄漏将被限制在任何持久存在的内容上。应用程序状态和会话状态。

这些区域内的任何内容都是首先要检查的。

此外,任何类中的静态对象,特别是列表或类似物品。


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