CLR内存不足异常

6
我们遇到了很多内存溢出异常,并且似乎无法诊断发生了什么。这似乎是一个问题,会导致内存使用量在几分钟内从300 MB上升到1 GB以上。现在,这是一个IIS应用程序,有三个应用程序域在单独的线程池中运行。
我们想要记录内存异常即将发生的时候,以便我们可以尝试找到模式。最好的方法是什么?
是否有一种方法每隔一分钟查询一次内存使用情况,并发送警报电子邮件?或者编写一个应用程序来监视CLR的内存使用情况?任何想法或方向都非常欢迎。

我正在使用性能监视器,但除非我在观察进程,否则它就没有那么有用。我只能看到发生了什么和什么时候发生了。我还使用了Red Gate内存分析工具,顺便说一下,它很棒 - 只是我似乎无法找到引起异常的页面或进程。


1
很感兴趣知道你发现了什么问题。 - Kev
7个回答

3

请在您的服务器上安装ADPlus(它是Windows Debugging Tools的一部分)。当您开始观察到异常高的内存使用率时,请使用以下命令捕获内存转储:

adplus -hang -p <PID> -quiet -o <dump file folder path>

<PID> 是工作进程的进程ID,您可以从tasklist.exe获取。

如果您不经常在此问题发生时周围,那么您可以使用DebugDiag自动捕获内存转储:

  1. 使用DebugDiag在泄漏跟踪模式下触发进程转储,当您的私有或虚拟内存使用量达到一定阈值时。 话虽如此,我并不总是发现这很可靠。

  2. 使用DebugDiag在崩溃模式下捕获转储,每当CLR异常抛出时都会捕获一个转储。 您可以使用高级设置来配置DebugDiag,在遇到类型为System.OutOfMemoryException的CLR异常时生成完整的内存转储。 这更可靠,并且肯定会触发。 只使用高级设置 -> 异常,不要触碰未配置的首次机会异常,将此设置保留为“无”。

一旦您拥有内存转储,就启动WinDBG,然后加载转储文件,加载SOS并开始探索。

Tess Ferrandez的博客是一个很好的.NET调试资源,她有很多关于如何追踪内存泄漏的文章和实验室(由于链接失效,这些是archive.org的链接):

如果它坏了,你应该修复它-内存问题文章

.NET调试演示实验室6:_内存泄漏
.NET调试演示实验室6:_内存泄漏-回顾
.NET调试演示实验室7:内存泄漏
.NET调试演示实验室7:内存泄漏-回顾

PerfMon计数器很有用,可以用来确认是否存在内存泄漏,但它们并不能完全告诉你整个故事。WinDBG和SOS是你需要使用的工具,可以找出内存使用的位置。


2
性能监视器,也称为Perfmon,它是你的朋友——它是免费的不会干扰轻量级的,如果你使用较少的采样(每几秒钟),它可以安全地运行在生产服务器上。它最基本的功能是对你的进程(w3wp.exe)进行内存和CPU使用率的采样,并将其存储在文件中。
由于你没有分享你在应用程序中正在做什么,所以我无法建议存储性能计数器,但在ASP.NET和.NET和CLR中有很多可供选择。
由于你遇到了CLR内存不足异常,我的直觉是由于某个对象被固定或其他原因导致GC无法工作。虽然也可能是未释放的非托管资源,如位图。
以下是我建议的计数器列表: .NET CLR Memory
  • GC句柄
  • 固定的对象
您的应用程序运行w3wp.exe的进程
  • 有几个,但主要是工作集

ASP.NET

管理的内存使用。

我不认为这是一个固定的对象,我们在代码中只有两个区域固定对象,它们似乎都很好,但这是一个很好的观点! - jquery auth
如果您的固定对象计数器增加,那么很容易看到。我强烈建议在启动时使用perfmon。 - Aliostad

1

试试 RedGate Memory Profiler。我想它应该可以用于 ASP.NET 网站(他们的性能分析器肯定可以)。


我觉得这是一个很好的工具,但如果您无法重现问题,则该工具就毫无用处,因为我不知道哪一系列事件导致了峰值,所以它没有帮助。尽管如此,它仍然是一个很棒的工具。 - jquery auth

0

内存分析只有在您大致知道如何查找内存峰值时才有用。 - jquery auth

0

0

当异常发生时,我会使用ADPlus以“崩溃”模式捕获内存转储,然后使用WinDbgSOS来找出占用所有内存的原因。


1
崩溃模式不会转储进程,因为OOM异常通常不会导致工作进程崩溃。 - Kev
当异常发生时,应该使用“挂起”模式来捕获进程转储。然后,通过转储分析可以显示堆上的内容。 - Lex Li
实际上,我犯了个错误,但你首先需要使用配置脚本来配置ADPlus。根据我遇到的情况,我发现DebugDiag更方便使用,适用于95%的情况。 - Kev

0

使用 dotTrace 或 YourToolkit .NET,您可以将分析器附加到 ASP 进程。

它们有试用版本,因此您不需要立即花钱。使用这些分析器,您可以选择时间轴,其中内存开始增加(您可以在图表中直观地看到内存使用情况),因此应该很容易选择范围并了解是什么导致内存使用量飙升如此之高。


"YourToolkit"是一个相当通用的名称。你能添加一些关于这个工具的参考吗?例如,它是这个吗?请通过编辑你的回答来回复,而不是在评论中回复(不要包含“编辑:”,“更新:”或类似的内容 - 回答应该看起来像今天写的)。 - Peter Mortensen

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