确认内存泄漏后,分四步排查:第一步用perfmon添加pool nonpaged/paged bytes和available mbytes计数器,采样10分钟持续监控8–24小时;第二步区分用户态(任务管理器+vmmap)与内核态(resmon+poolmon);第三步针对wmi、iis(appcmd list wp)、java(jstat/jmap)等高频场景验证;第四步用procdump或内核转储结合windbg分析(!vm 1/!poolused 2/!heap -s)。
windows服务器因内存泄漏频繁宕机,核心表现是:可用内存持续下降、系统响应迟缓、最终触发蓝屏或服务自动终止。这不是简单“杀进程”能解决的问题,关键在于定位泄漏源头——它可能藏在用户态应用、内核驱动、wmi服务,甚至iis工作进程中。排查必须分阶段推进,从确认泄漏存在开始,再到锁定具体模块。
第一步:用性能监视器(PerfMon)确认泄漏模式
内存泄漏的本质是“内存使用量随时间单向增长且不回落”。不能只看任务管理器的瞬时百分比。
- 打开perfmon,添加以下三个关键计数器:
- Memory\Pool Nonpaged Bytes(非分页缓冲池)——内核驱动泄漏的典型指标,持续上涨说明驱动或系统服务有问题
- Memory\Pool Paged Bytes(分页缓冲池)——WMI、某些服务或驱动也可能占用这里
- Memory\Available MBytes(可用物理内存)——应呈现缓慢但明显的下降趋势,而非短期波动
- 设置采样间隔为600秒(10分钟),连续记录至少8–24小时;若发现非分页池在几小时内上涨超300MB且不回落,基本可判定为内核级泄漏
第二步:区分泄漏层级——用户态还是内核态
先缩小范围,再深入分析。不同层级对应不同工具和路径:
- 用户态泄漏(如Java、.NET、w3wp.exe):打开任务管理器 → “详细信息”选项卡 → 按“内存(工作集)”排序,观察是否有进程内存持续攀升(例如每小时涨500MB以上);对疑似进程,用VMMap打开,重点关注“Private Data”列是否不断增大
- 内核态泄漏(驱动或系统服务):打开资源监视器(resmon)→ “内存”选项卡 → 查看底部“硬错误”和“内核内存”区域;若“非分页池”占用远高于正常值(如服务器空闲时仍超800MB),需进一步用poolmon定位驱动标签(配合windbg分析转储)
- 特别注意WMI服务:若svchost.exe(托管Winmgmt)或WmiPrvse.exe内存/句柄数居高不下且重启后缓解、几小时后复发,大概率是WMI提供程序泄漏;可运行sc config winmgmt type= own将其隔离到独立svchost,再用tasklist /svc验证
第三步:针对常见场景快速验证
不必从零开始,优先检查高频泄漏点:
- IIS应用程序池:运行%windir%\System32\inetsrv\appcmd list wp匹配w3wp.exe PID,再用PerfMon监控该进程的\Process(w3wp)\Private Bytes;若稳定上涨,收集其用户模式内存转储(使用ProcDump:procdump -ma -n 3 -s 60 w3wp.exe leak_dump)
- Java应用:用jstat -gc {pid}查看老年代是否持续增长且GC无效;结合jmap -histo {pid}查大对象分布;必要时生成heap dump用Eclipse MAT分析
- 第三方服务或驱动:检查最近安装的软件、更新的硬件驱动;在安全模式下观察内存是否稳定;使用driverquery /v导出驱动列表,比对已知问题版本
第四步:抓取并分析内存转储(关键证据)
当确认泄漏存在但无法通过进程名判断时,需获取内存快照:
- 对高内存进程(如w3wp、java、svchost),用ProcDump命令:procdump -ma -c 90 -s 10 -n 3 {pid} memory_full.dmp(当CPU或内存超90%时,每10秒捕获一次,共3次)
- 对系统级问题,启用内核内存转储(控制面板 → 系统 → 高级系统设置 → 启动和故障恢复 → 写入调试信息 → 选择“内核内存转储”)
- 用WinDbg加载dmp文件,执行:!vm 1看整体内存分布,!poolused 2排非分页池占用,!heap -s查用户堆碎片











