如何确定哪个应用程序正在泄漏未分页的内存?


8

最近,我们的实时服务器出现问题,导致我们的Web应用程序停止响应。我们得到的都是503错误,直到重新启动服务器,然后一切正常。最终,我将其追溯到httperr.log,发现了很多1_Connections_Refused错误。

进一步的调查似乎表明我们已经达到了非分页池限制。从那时起,我们一直在使用Poolmon.exe监视未分页的池内存,并且我们认为我们已经确定了导致问​​题的标签。

Tag   Type    Allocs       Frees       Diff       Bytes      Per Alloc
Even  Nonp  51,231,806   50,633,533   684,922   32,878,688      48

如果我们使用poolmon.exe / g,它将映射的驱动程序显示为[<未知>事件对象]。

根本没有帮助。我的团队花费了大量时间来研究此问题,但是还没有找到将其范围缩小到特定应用程序或服务的过程。我感觉到,大多数人似乎通过杀死计算机上的进程来解决问题,直到他们看到未分页的内存重置为止。这并不是在生产机器上工作时想要看到的。

如果我打开任务管理器并查看进程列表。我看到MailService.exe的NP池值为105K,比第二个列出的进程的值高36K。由于过去我们的邮件服务器存在一些问题(可能与此问题相关,也可能与该问题无关),我的直觉是这是导致此问题的原因。

但是,在我们重新启动服务之前,我想拥有的不仅仅是确定的感觉。

我也尝试使用poolmon.exe / c,但这总是返回错误:

unable to load msvcr70.dll/msvcp70.dll

而且它不会创建localtag.txt。我的同事不得不从互联网上下载pooltag.txt,因为我们无法确定它的位置。我们没有安装Win调试器或Win DDK(我可以看到)。可能是由于没有安装上述任何一个错误而导致的,但我不知道。

最后我尝试了:

C:\windows\system32\driver\findstr /m /l Even *.sys

这返回了相当大的.sys文件列表,再次对当前的问题完全没有帮助。

所以我的问题是:还有其他方法可以缩小导致此内存泄漏的原因吗?

更新:

如下所示,我已经记录了最后一天左右的池未分页字节数,以查看是否有任何趋势。在大多数情况下,所有过程的使用似乎都是静态的。他们中的两个看起来略有滴答声。在接下来的几天中,我将继续进行监视。

我也忘记了前面提到的任何一个进程似乎都没有使用过多的句柄。

更新2:

最近几周我一直在监视它。在此期间,单个进程的非分页字节池和总的非分页字节池都保持相对稳定。在此期间,Windows已更新,服务器重新启动,因此我想知道是否已经解决了问题。现在,我肯定没有看到非分页字节池的持续增长。


为什么不使用perfmon监视所有进程的池非分页字节数,并寻找具有失控的非分页池内存的进程?
joeqwerty

我刚刚玩过Performance Monitor,并按照您的建议进行设置。但是,它并没有真正告诉我看任务管理器所不知道的任何内容。MailService的Nonpaged Pool使用率最高,但仅为106K。因此,这并不是我一直在寻找的吸烟枪。
开发人员

寻找随着时间的推移在进程中增加池非分页字节数。通过在任何时候及时查看按过程使用情况可能并不容易看出。您可以通过设置计数器日志以保存到CSV文件并使用Excel打开该日志来分析每个进程不断增加的使用情况,轻松地随时间捕获使用情况。从系统启动起,任何显示池非分页字节增加10%或更多的进程都在泄漏内存,并且很可能是导致该问题的进程
joeqwerty 2011年

PAL工具是帮助捕获和分析相关计数器数据的便捷工具,可在以下位置找到:pal.codeplex.com/releases/view/51623#ReviewsAnchor。这是我使用过的较新版本,但是有一个x86版本,看起来可以在W2K3上使用。
joeqwerty 2011年

我已经设置了一个日志文件来记录NP池字节。Poolmon现在说我的非页面内存使用量为68MB。在试图解决这个问题的几个小时中,它增长了大约2-3MB。但是,进程的NP值没有相应的增长(我可以看到)。实际上,针对各个进程的NP池值远不接近该数字。即使我将所有列出的np池值加起来,总数也很幸运为1MB而不是68MB。但是也许我在这里错过了一些东西。
开发人员

Answers:


6

我已经对此进行了大约6-7周的监视,最终可以对这个问题给出明确的答案。

首先,单个进程的“非分页字节”并没有真正告诉我任何有用的信息,因为它们的使用似乎都是静态的。出现峰值,但使用之后总是返回到基准线。

非分页字节内存总量在一段时间内也是静态的,但随后逐渐增加,然后增加。峰值之后,大约释放了一半的内存,然后一段时间(在较高级别)再次保持静态,直到模式重复。查看图表,我注意到这些峰值似乎是有规律地分布的,事实证明,它们彼此间隔2周,并且总是在星期日发生。

因此,下一个问题是:每两周的星期日运行一次?我去了Event Viewer,每次出现峰值时McAfee都在运行。我还认为,通过频繁登录服务器以监视问题,由于McAfee具有实时扫描程序,我们无意中使问题变得更糟,并且我相信这导致了我们所看到的较小的增长。

我认为扫描是预定任务,这也解释了为什么我们看到Pool Memory中的NP Memory附加到Event objects标签而不是McAfee特定标签的原因。这是使我们真正走下花园道路的主要因素。

现在,我们终于知道是什么导致泄漏的了,我们可以对此采取措施。令人难以置信的是,花了这么长时间才找到它。

更新:作为最后的说明。迈克菲在周末进行了更新,这完全解决了我们的非页面内存问题。

更新2:由于我刚刚对此表示赞成,因此我将对此进行进一步的更新。最初,对McAfee的更新确实可以解决我们的问题,即我们不再看到NP Memory定期出现大量峰值。我还注意到,自从更新以来,McAfee现在似乎不再默认将日志写入事件查看器,该事件查看器在主动扫描时隐藏。

但是我们仍然看到NP内存使用量逐渐增加。到了现在,我们需要每两周左右重新启动服务器一次。真是太糟糕了,我们最近购买了一台新服务器,希望更新的硬件和软件能够解决此问题,但是我们仅安装Windows Server 2008,SQL Server 2008 R2和McAfee的全新服务器仍然显示NP内存泄漏。直到我完全删除McAfee之后,泄漏才停止,并且即使我们设置了所有软件以准备切换到该服务器之后,泄漏仍然保持静态。

从那以后,我已经读过书,而且我不知道这是否是真的,问题不是出自McAfee,而是McAfee使用的某些Windows例程导致NP内存泄漏。显然,网络活动是泄漏的原因,即更多的网络活动=>更大的泄漏。这似乎与我们的经验一致,因为随着服务器的繁忙,泄漏变得更加严重。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.