快速诊断内存泄漏

一年眼看就到了尽头。下半年我比较忙,发生了太多的事情,半年都没写博客了,现在又捡起来,显得有些生疏。值此新旧更替之际,诚挚祝愿各位新老朋友在新的2012年里万事如意,心想事成!回首来看,以往的文章多少显得篇幅太长,比较累赘,在新的2012年里,我将专注面向 IT 专业人士,减少对基础的赘述,如您有什么不明白的地方,欢迎在文后评论留言,也可在微博给我发消息。

 

在这一年里,是否有遗漏什么事情呢?哈哈,也许,电脑有时候遇到了写得不好的程序或者驱动,也会泄漏内存呢。今天我们就一起在2011年的最后时刻一起讨论一下如何快速检测内存泄漏。

 

我们知道,当程序向内存池申请分配内存后,若不释放,就会产生所谓的"内存泄漏"。这样的后果是严重的:Windows会越来越慢,如果有限的内存池被完全耗尽,那就会发生各种错误和异常。当您觉得系统在启动和登录后越来越慢时,您大致就可以开始怀疑是否存有内存泄漏了。现在介绍一种能够简易诊断的方式,这种方式虽不能直接指出是哪个用户态或者内核态的程序造成的内存泄漏,但是能够诊断是否存有泄漏情况,我们一起来看看。

 

1. 启动"性能监视器"(perfmon);

2. 添加三个特征计数器:

父类别

计数器名称

Memory

Pool Nonpaged Bytes

Memory

Pool Paged Bytes

Paging File

% Usage

 

由于内存泄漏一般都要数小时才能检测到并确诊,所以这个方法虽叫"快速",实际上还是比较缓慢的,但是最简易的方式了。这里,我建议大家将性能计数器的属性中的采样间隔和持续时间都设得久一些,这样采样点会较少,而两个采样点之间的数据变化也会比较明显,容易直观比较。

 

 

开始采样后,您需要启动您认为可疑的应用程序,或者干脆就在您认为会有内存泄漏的现有系统环境下直接开始监测。如果您是在添加计数器后才开始启动一些可疑程序的,那么您会看到一个前期过程内,计数器的值会变化较大,但是,过段时间就会趋于相对稳定。那么在稳定后的数据规律性变化则起到关键的判别作用。值得注意的是,在检测期间,就不要再使用系统了,也不要对应用产生干扰,以免造成计数器的无关变化。

 

这里我给出一张对照表,可以帮助您通过稳定后的指标变化来判断是否有内存泄漏:

 

泄漏来源

计数器指标变化规律

说明

用户态

Pool Paged Bytes 和 page file Usage 会随时间不断上升

用户态程序内存泄漏总是发生在换页内存池中

内核态

Pool Nonpaged Bytes 随时间不断上升 (Pool Paged Bytes 也能随时间上升)

内核态内存泄漏通常消耗非换页内存池

 

注意,万一在计数点遇到应用程序缓存数据,则会造成计数器计数值的"异常",这对于我们的内存泄漏判断而言将是种误报。需根据后续的情况走势来看。

 

这里,我进行了30多分钟的检测,我的采样间隔是10分钟一次,那么下图中将有三次采样的数据。可以看出,这是相对稳定的状态,没有内存泄漏。(建议您至少监测1小时以上)

 

 

如果您想搜集详细的日志,不妨在"数据收集器"的"用户定义"下创建一个收集器,然后您可以在一段时间后查看报告。这样可以有效避免实时监测窗口的记录线条在到达右边底部时重新从左边开始覆盖已有数据。

 

好了,到这里本文就介绍完了。如果您是专业开发人员,需要进一步检测应用程序的用户态/内核态内存泄漏情况,那就需要用更加专业的工具了,例如诊断内核态泄漏,可以使用 Driver Verifier、内核调试器和 Windows Driver Kit 里面的 PoolMon 工具;对于用户态内存泄漏诊断,可以使用 WinDbg 自带的 UMDH 工具或者针对具体的进程添加更多的计数器… 这些都不在本文的讨论范围内了。希望大家怀疑有内存泄漏时,都能通过这一简易办法进行确认哦~

 

咱2012年再见~ J

posted @ 2012-01-01 00:43  佘华煜  阅读(3107)  评论(7编辑  收藏  举报