示例 9:检测池内存泄漏

以下示例使用 GFlags 在注册表中设置系统范围的 Enable pool 标记 标志。 然后,它使用 PoolMon (poolmon.exe) (Windows 驱动程序工具包中的一个工具)显示内存池的大小。

PoolMon 监视分页和非分页内存池中的字节,并按池标记对其进行排序。 通过定期运行 PoolMon,可以识别随时间不断扩展的池。 此模式通常表示内存泄漏。

注意 池标记在 Windows Server 2003 及更高版本中永久启用。 在这些系统上,“全局标志”对话框中的“启用池标记检查”框灰显,用于启用或禁用池标记的命令将失败。 如果未启用池标记,PoolMon 将失败并显示以下消息:“查询池标记失败 c0000002。

检测池内存泄漏

  1. 若要为早于 Windows Server 2003 的 Windows 版本中的所有进程启用池标记,请在注册表中设置系统范围的 “启用池标记” 标志。 以下命令行使用标志缩写方法,但可以按其十六进制值标识标志,也可以使用 “全局标志 ”对话框:

    gflags /r +ptg 
    
  2. 重新启动计算机,使注册表更改生效。

  3. 使用以下命令定期运行 PoolMon。 在此命令中, /b 参数按大小降序对池进行排序。

    poolmon /b 
    

    作为响应,PoolMon 以降序显示内存池的分配,包括分配操作数和可用操作数,以及池中剩余的内存量 (字节列) 。

    Memory: 16224K Avail: 4564K PageFlts: 31 InRam Krnl: 684K P: 680K
     Commit: 24140K Limit: 24952K Peak: 24932K  Pool N: 744K P: 2180K
    
     Tag  Type    Allocs          Frees         Diff   Bytes      Per Alloc
    -----------------------------------------------------------------------
    
     CM   Paged    1283 (   0)    1002 (   0)    281 1377312 (     0) 4901
    Strg  Paged   10385 (  10)    6658 (   4)   3727  317952 (   512)   85
     Fat  Paged    6662 (   8)    4971 (   6)   1691  174560 (   128)  103
    MmSt  Paged     614 (   0)     441 (   0)    173   83456 (     0)  482
    

    如果分配的 “字节数” 列中的值由于没有明显原因而持续扩展,则该池中可能存在内存泄漏。

  4. 清除 “启用池标记” 标志。

    以下命令行使用标志缩写方法,但可以按其十六进制值标识标志,也可以使用 “全局标志 ”对话框:

    gflags /r -ptg 
    
  5. 重启 Windows 以使注册表更改生效。

注意 使用追加符号 (>>) 将 PoolMon 输出重定向到日志文件。 稍后,可以检查日志文件中的池大小趋势。 例如:

poolmon.exe /b >> poolmon.log