关键不是看“占得多”,而是看“涨不停、不回落”;perfmon通过private bytes(用户模式)、pool nonpaged bytes(内核模式)等计数器追踪单向不可逆增长趋势,结合handle count、available mbytes联动分析,精准识别内存泄漏。
追踪内存泄漏进程,关键不是看“占得多”,而是看“涨不停、不回落”。任务管理器只能告诉你谁当前吃内存多,但无法反映随时间推移的异常增长趋势——这正是内存泄漏最典型的特征。
用 PerfMon 抓住泄漏的核心指标
Windows 自带的性能监视器(PerfMon)是定位泄漏最直接的工具。打开方式:Win + R → 输入 perfmon → 回车。
- Process → Private Bytes:这是判断用户模式泄漏的黄金指标。它代表进程独占分配的内存总量(含虚拟内存),不受系统缓存干扰。若该值在空闲状态下仍持续单向上升,基本可确认泄漏。
- Process → Handle Count:句柄数同步上涨,往往说明文件、窗口、事件等资源未释放,常与内存泄漏伴生。
- Memory → Pool Nonpaged Bytes 和 Pool Paged Bytes:两者联动观察。若仅 Nonpaged 池持续上涨,且 Available MBytes 不可逆下降,大概率是驱动或内核组件泄漏。
设置有效的监控策略
采样太密易受瞬时波动干扰,太疏又可能错过拐点。推荐组合:
- 采样间隔设为 15–60 秒(用户模式排查)或 600 秒(10 分钟)(内核模式,需长时间观察);
- 总监控时长至少 30 分钟以上,覆盖启动→操作→空闲全过程;
- 使用“数据收集器集”功能,把数据导出为 CSV 或 BLG 文件,方便后续用 Excel 绘图分析趋势;
- 监控期间尽量避免运行其他大型程序,减少干扰变量。
识别泄漏的典型行为模式
不是所有内存增长都危险,重点抓“反常性”:
- 执行相同操作(如打开/关闭一个窗口、刷新一次列表)后,Private Bytes 每次都比前一次更高,且空闲 5 分钟后仍不回落;
- 进程已最小化或后台空闲,但 Handle Count 和 Private Bytes 仍在缓慢爬升;
- Working Set 随 Private Bytes 扩大,而系统“可用内存”持续减少,“已提交”数值明显增加;
- .NET 应用中,.NET CLR Memory → # Bytes in all Heaps 与 Private Bytes 同步上涨,且对象实例数量只增不减。
确认后下一步怎么走
PerfMon 能明确告诉你“哪个进程在泄漏”和“属于用户模式还是内核模式”,但不会指出具体哪行代码出问题:
- 确认是用户模式泄漏(如 chrome.exe、yourapp.exe):后续可用 UMDH 工具抓堆栈快照对比,定位到具体分配函数;
- 确认是内核模式泄漏(Pool Nonpaged Bytes 异常上涨):配合 poolmon 查看高消耗 Tag,再用 driverquery /v 或 findstr 反查对应驱动;
- 对 .NET 程序,还可附加 WinDbg 使用 !dumpheap -stat 和 !gcroot 追踪托管对象生命周期。











