CLR内存exception

我们得到了很多内存exception,我们似乎无法诊断出现了什么。 这似乎是一个问题,会在几分钟内将内存使用量从300兆的增加到千兆以上。 现在这是一个IIS应用程序,有3个应用程序域在不同的线程池中运行。

我们想记录内存exception即将发生的时间。 所以我们可以尝试找到一种模式。 我的问题是:最好的方法是什么? 有没有办法每分钟查询内存使用情况,看看它有多高,并发送警报电子邮件。 或者编写一个可以监控CLR内存使用情况的应用程序? 一个想法或方向更受欢迎。

编辑

我正在使用Perfmon,但除非我正在观察这个过程,否则它不是那么有用。 我只能看到是什么以及什么时候。 我还使用了红门内存配置文件工具,顺便说一句,这真是太棒了,只是我似乎无法点击导致exception的页面或进程。

在服务器上安装ADPlus(它是Windows调试工具的一部分)。 当您开始观察exception高的内存使用量时,使用以下方法捕获内存转储:

adplus -hang -p  -quiet -o  

是可以从tasklist.exe获取的工作进程的进程ID。

如果您在发生此问题时并不总是在身边,那么您可以使用DebugDiag自动捕获内存转储:

  1. 在专用或虚拟内存使用达到特定阈值时,在泄漏跟踪模式下使用DebugDiag来触发进程转储。 也就是说,我并不总是觉得这很可靠。

  2. 在抛出CLRexception时,在崩溃模式下使用DebugDiag捕获转储。 您可以使用“高级设置”将DebugDiag配置为在遇到类型为System.OutOfMemoryException的CLRexception时生成完整内存转储。 这更可靠,肯定会触发。 仅使用“高级设置” – >“例外”,不要触摸“未配置的第一次机会例外”,将此设置保留为“无”。

一旦你的内存转储启动WinDBG,加载转储文件并加载SOS并开始讨论。

Tess Ferrandez的博客是一个很棒的.NET调试资源,她有很多关于如何跟踪内存泄漏的文章和实验:

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

.NET调试演示实验6:_Memory Leak
.NET调试演示实验6:_Memory泄漏 – 回顾
.NET调试演示实验7:内存泄漏
.NET调试演示实验7:内存泄漏 – 回顾

PerfMon计数器很有用,可用于确认您有内存泄漏,但它们并不能说明整个故事。 WinDBG和SOS是您需要用来查找内存使用位置的工具。

Perfmonnce Perfmon是你的朋友 – 它是免费的不侵入性重量轻 ,如果你使用频率较低的采样(每隔几秒钟)就可以安全地在生产服务器上运行。 它可以做的最小化是为您的进程(w3wp.exe)采样内存/ CPU使用并将它们存储在一个文件中。

既然你没有在应用程序中共享你正在做的事情,我就不能建议存储性能计数器,但ASP.NET和.NET以及CLR中有很多。

由于你正在获得CLR内存exception,我的预感是由于固定对象或其他东西而导致GC不能正常工作。 我怀疑它是非托管资源,如位图没有被释放,尽管它​​可能是。

这是我建议的计数器列表:

.NET CLR内存

  • GC手柄
  • 固定物体

运行应用程序的w3wp.exe的进程

  • 一对夫妇,但主要是工作集

ASP.NET

  • 使用托管内存

试试RedGate Memory Profiler 。 我认为它适用于ASP.NET站点(他们的性能分析器肯定会)。

使用内存分析器 。 那里有几个很好的,例如JetBrains dotTrace或Red Gate的ANTS Memory Profiler 。 stackoverflow上有很多讨论,还有很多其他提示和建议。

如果你买不起一个好的分析器,你应该利用微软推荐的内容, http://msdn.microsoft.com/en-us/library/ee817663.aspx

我会在“崩溃”模式下使用ADPlus在发生exception时捕获内存转储,然后使用WinDbg和SOS来确定占用所有内存的内容。

使用dotTrace或YourToolkit .Net,您可以将探查器附加到ASP流程,它们具有试用版,因此您无需立即花钱。 使用这些分析器,您可以选择内存开始增加的时间线(您可以在图形中直观地看到内存使用情况),因此应该很容易选择范围并了解导致内存使用率如此之高的原因。