示例 9:检测池内存泄漏
以下示例使用 GFlags 在注册表中设置系统范围的 Enable pool 标记 标志。 然后,它使用 PoolMon (poolmon.exe) (Windows 驱动程序工具包中的一个工具)显示内存池的大小。
PoolMon 监视分页和非分页内存池中的字节,并按池标记对其进行排序。 通过定期运行 PoolMon,可以识别随时间不断扩展的池。 此模式通常表示内存泄漏。
注意 池标记在 Windows Server 2003 及更高版本中永久启用。 在这些系统上,“全局标志”对话框中的“启用池标记检查”框灰显,用于启用或禁用池标记的命令将失败。 如果未启用池标记,PoolMon 将失败并显示以下消息:“查询池标记失败 c0000002。
检测池内存泄漏
若要为早于 Windows Server 2003 的 Windows 版本中的所有进程启用池标记,请在注册表中设置系统范围的 “启用池标记” 标志。 以下命令行使用标志缩写方法,但可以按其十六进制值标识标志,也可以使用 “全局标志 ”对话框:
gflags /r +ptg
重新启动计算机,使注册表更改生效。
使用以下命令定期运行 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
如果分配的 “字节数” 列中的值由于没有明显原因而持续扩展,则该池中可能存在内存泄漏。
清除 “启用池标记” 标志。
以下命令行使用标志缩写方法,但可以按其十六进制值标识标志,也可以使用 “全局标志 ”对话框:
gflags /r -ptg
重启 Windows 以使注册表更改生效。
注意 使用追加符号 (>>) 将 PoolMon 输出重定向到日志文件。 稍后,可以检查日志文件中的池大小趋势。 例如:
poolmon.exe /b >> poolmon.log