使用 PoolMon 查找内核模式内存泄漏

如果怀疑存在内核模式内存泄漏,可以使用 PoolMon 工具确定哪个池标记与泄漏相关联。

PoolMon (Poolmon.exe) 按池标记名称监视池内存使用情况。 此工具包含在 Windows 驱动程序工具包 (WDK) 中。 有关详细信息,请参阅 PoolMon

GFlags 池设置

某些 GFlags 设置(如特殊池)将影响内存池的使用方式。 有关详细信息,请参阅 GFlags配置特殊池

使用 PoolMon

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 

PoolMon 具有命令键,这些命令键根据各种条件对输出进行排序。 选择与每个命令关联的字母,以便使用数据。 每个命令需要几秒钟才能正常工作。

排序命令包括:

命令键 操作
P 将显示的标记限制为非分页池字节和/或分页池字节。 按该顺序重复按 P 循环遍历每个选项。
B 按最大字节使用量对标记进行排序。
M 按最大字节分配数对标记进行排序。
T 按标记名称按字母顺序对标记进行排序。
E 使显示内容在底部包含分页和未分页的总计。
A 按分配大小对标记进行排序。
F 按自由操作对标记进行排序。
S 按分配和释放之间的差异对标记进行排序。
Q 退出 PoolMon。

在 PoolMon 中显示驱动程序名称

可以使用 PoolMon /g 参数显示分配每个池标记的 Windows 组件和常用驱动程序的名称。 如果在具有特定标记的分配中发现问题,此功能可帮助你识别有问题的组件或驱动程序。

组件和驱动程序列在“Mapped_Driver”列中,即显示中最右侧的列。 Mapped_Driver 列的数据来自 pooltag.txt,该文件随 WDK 一起安装。

以下命令演示如何使用 /g 参数添加Mapped_Driver列。

poolmon /g "C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\triage\pooltag.txt"

显示特定池

使用 /i 参数显示以特定字符串开头的池标记,例如 Hid

poolmon /iHid? /g "C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\triage\pooltag.txt"

 Memory:33473120K Avail:20055132K  PageFlts:     5   InRam Krnl:10444K P:1843072K
 Commit:15035764K Limit:67027552K Peak:16677444K            Pool N:1023400K P:1955448K
 System pool information
 Tag  Type     Allocs            Frees            Diff       Bytes                 Per Alloc Mapped_Driver

 HidC Paged      1667 (   0)      1659 (   0)        8         896 (          0)         112 [hidclass.sys - HID Class d 
 HidC Nonp      17375 (   0)     17256 (   0)      119       19808 (          0)         166 [hidclass.sys - HID Class d 
 HidP Nonp       1014 (   0)       998 (   0)       16        6704 (          0)         419 [hidparse.sys - HID Parser]

使用 PoolMon 实用工具查找内存泄漏

下面是使用 PoolMon 实用工具查找内存泄漏的一种方法:

  1. 启动 PoolMon。

  2. 如果已确定泄漏发生在非分页池中,请选择 P 一次。 如果已确定它发生在分页池中,请选择 P 两次。 如果不知道,请不要选择 P,以便包括这两种类型的池。

  3. 选择 B 可按最大字节使用量对显示进行排序。

  4. 开始测试。 从屏幕复制输出,例如,拍摄屏幕截图并保存。

  5. 每半小时拍摄一次新的屏幕截图。 通过比较屏幕截图,确定哪些标记的字节正在增加。

  6. 停止测试并等待几个小时。 确定此时释放了多少标记。

通常,在应用程序达到稳定运行状态后,它会以相同的速率分配内存和可用内存。 如果分配内存的速度比释放内存快,则内存使用量会随着时间的推移而增长。 这通常表示内存泄漏。

解决泄漏问题

确定与泄漏关联的池标记后,你可能已获得有关泄漏的全部需要了解的内容。 如果需要确定分配例程的特定实例导致泄漏,请参阅 使用内核调试器查找内核模式内存泄漏