引入
在做性能分析的时候,Windows 中自带的 Performance Monitor 非常有效,可以用来分析一些非常复杂的性能问题。
首先,先了解下常用的内存计数器:
内存计数器
下面总结了常见的 Memory 计数器,包含 含义、用途以及一些 补充说明。
计数器 | 含义 | 用途 | 补充说明 |
---|---|---|---|
\Memory\Page Faults/sec | 每秒发生的页面错误数量(包含软错误与硬错误)。 | 观察整体缺页情况,若数值过高需结合 Pages/sec 判断是否频繁磁盘 I/O(硬错误多)。 | 软错误不需要访问磁盘;硬错误需要从磁盘换页。 |
\Memory\Available Bytes | 系统当前可用且未被使用的物理内存容量(字节)。 | 数值过低表示内存紧张,可能导致更频繁的分页和性能下降。 | 与 \Memory\Available KBytes 、\Memory\Available MBytes 同义,单位不同。 |
\Memory\Committed Bytes | 系统已“提交”的虚拟内存总量(所有进程 + 内核),需要物理内存或页面文件支持。 | 若此值不断攀升,可能暗示内存泄漏或应用正消耗大量内存。 | 可与 Commit Limit 对比,观察是否接近系统可承诺上限。 |
\Memory\Commit Limit | 当前系统能承诺(Commit)的虚拟内存上限(结合物理内存 + 页面文件)。 | 当 Committed Bytes 逼近 Commit Limit,系统会面临内存压力,甚至可能触发 Out of Memory。 | 如果需要提高此上限,可增大物理内存或页面文件大小。 |
\Memory\Write Copies/sec | “写时复制”(Copy on Write)操作引发的页面错误速率。 | 多进程共享内存时,一旦有进程写入,就会触发写时复制。 | 对调试多进程共享内存或监控应用内存分配行为有帮助。 |
\Memory\Transition Faults/sec | 页面从“过渡状态”转为“可访问状态”时的页面错误速率。 | 不一定需要磁盘访问,通常是页面还在内存中但需更新映射。 | 可细分页面错误原因,区分硬错误、软错误。 |
\Memory\Cache Faults/sec | 文件系统缓存(File System Cache)读取不命中的页面错误速率。 | 若数值长期过高,表示缓存效率不佳,可能导致更多后续磁盘访问。 | 不一定直接代表磁盘 I/O,因为有时可从内存其他区域获取所需页面。 |
\Memory\Demand Zero Faults/sec | 进程请求新的“零页”(zeroed page)导致的页面错误速率。 | 当应用分配新的匿名内存时触发,通常属于正常现象。 | 若值异常高,可表示进程短时间内申请大量内存。 |
\Memory\Pages/sec | 每秒从磁盘换入或换出内存的页面总数(page-in + page-out)。 | 值过高通常意味着系统在频繁进行磁盘 I/O,暗示内存紧张或进程频繁读取新数据。 | 常与 \Memory\Page Faults/sec 联合分析,判断硬错误比例。 |
\Memory\Pages Input/sec | 每秒从磁盘读取进内存的页面数。 | 监控读操作频率,若过高说明缺页换入频繁或 I/O 操作多。 | 通常与 \Memory\Page Reads/sec 一起观察。 |
\Memory\Page Reads/sec | 每秒真正从磁盘执行的页面读操作次数。 | 若此值显著高,说明硬错误频繁,需要频繁从磁盘加载页面。 | 与 \Memory\Pages Input/sec 区分:一个读操作可包含多页数据,或相反。 |
\Memory\Pages Output/sec | 每秒写出到磁盘的页面数(换出)。 | 若长期高,可能系统正在频繁清理或交换内存页面。 | 可能由内存压力或后台写回操作引起。 |
\Memory\Page Writes/sec | 每秒执行的页面写 I/O 操作次数(换出)。 | 值高说明换出频繁,系统可能内存不足或进行大量后台写操作。 | 与 \Memory\Pages Output/sec 区分:一个写操作可包含多页数据。 |
\Memory\Pool Paged Bytes | 内核分页池(Paged Pool)当前占用的字节数。 | 监控内核组件或驱动程序对分页池的使用情况。 | 值若持续增长,需排查是否有内存泄漏。 |
\Memory\Pool Nonpaged Bytes | 内核非分页池(Nonpaged Pool)当前占用的字节数。 | 该部分不会被换出到磁盘,若持续上升会挤占可用内存。 | 同样可能暗示驱动或内核对象有内存泄漏。 |
\Memory\Pool Paged Allocs | 内核分页池分配操作次数。 | 观察分页池的分配频率,若高且 Pool Paged Bytes 不断增大,需排查异常分配。 | 帮助识别内核对象分配过度情况。 |
\Memory\Pool Nonpaged Allocs | 内核非分页池分配操作次数。 | 同理,用于监控非分页池的分配行为和频度。 | 高分配次数 + Pool Nonpaged Bytes 激增要格外关注。 |
\Memory\Free System Page Table Entries | 剩余的系统页表项(PTE)数量。 | 若该值过低,会导致系统无法再为进程分配新的页表,出现内存错误或不稳定。 | 主要在系统级内存调优或排错时查看。 |
\Memory\Cache Bytes | 文件系统缓存(File System Cache)使用的总字节数(虚拟层面)。 | 反映文件缓存整体规模,帮助了解系统对文件的缓存情况。 | 与实际驻留内存(\Memory\System Cache Resident Bytes )区分。 |
\Memory\Cache Bytes Peak | 文件系统缓存使用量的历史峰值(虚拟层面)。 | 了解缓存的最大规模,是否在高负载期间占用内存过多。 | 若峰值过大可能挤占应用进程内存,从而引发频繁分页。 |
\Memory\Pool Paged Resident Bytes | 内核分页池实际驻留在物理内存中的大小。 | 与 \Memory\Pool Paged Bytes 区分,后者是分配总量,本计数器仅指当前在 RAM 中的那部分。 | 判断分页池在物理内存中驻留的程度。 |
\Memory\System Code Total Bytes | 系统可执行代码(内核 / 驱动等)在虚拟地址空间中的大小。 | 可监控内核 / 驱动使用的总体虚拟地址空间规模。 | 若持续飙升,需检查是否有异常模块或代码重复加载。 |
\Memory\System Code Resident Bytes | 系统可执行代码实际驻留在物理内存中的大小。 | 观察内核、驱动程序等对物理内存的占用,防止挤占用户态进程内存。 | 如果显著过高,要警惕驱动泄漏或内核态占用过多资源。 |
\Memory\System Driver Total Bytes | 系统驱动程序(driver)使用的虚拟地址空间总量。 | 监控驱动占用规模,帮助识别潜在驱动内存问题。 | 可能结合事件日志或专门驱动调试工具分析更详细信息。 |
\Memory\System Driver Resident Bytes | 系统驱动程序实际驻留在物理内存中的大小。 | 若该值过高,或持续增长,需排查驱动的内存占用情况。 | 与 \Memory\Pool Nonpaged Bytes 一起看,了解驱动是否占用非分页池过多。 |
\Memory\System Cache Resident Bytes | 文件系统缓存当前实际驻留在物理内存中的大小。 | 值大说明缓存利用多,读取文件时可减少磁盘 I/O,但若挤占过多会影响应用可用内存。 | 可与 \Memory\Cache Bytes 、\Memory\Available Bytes 等计数器对比观察整体内存状态。 |
\Memory\% Committed Bytes In Use | (Committed Bytes / Commit Limit) × 100%。 | 观察已提交内存占系统承诺上限的比率,高值说明内存压力大。 | 若接近 100%,意味着接下来可能会触发内存不足等风险。 |
\Memory\Available KBytes | 与 \Memory\Available Bytes 同义,单位为 KB。 | 更直观地查看可用内存,避免大数字不易读的问题。 | 本质与 Available Bytes 指标相同,只是换了单位显示。 |
\Memory\Available MBytes | 与 \Memory\Available Bytes 同义,单位为 MB。 | 同上。 | 建议结合应用实际需求来判断是否内存不足。 |
\Memory\Transition Pages RePurposed/sec | 每秒从过渡列表(Transition List)重新分配给其他用途的页面数量。 | 展示系统对处于过渡状态的页面的再利用效率。 | 若此值较高,说明页面频繁从过渡状态被抢占或回收再分配。 |
\Memory\Free & Zero Page List Bytes | 处于“Free”或“Zero”列表中的物理页总字节数。 | 该值高说明系统有足够的空闲或归零页面可立即分配给进程。 | 若数值偏低,进程请求新页面时可能会引发额外延迟或分页故障。 |
\Memory\Modified Page List Bytes | 被修改但尚未写回磁盘的页面所占用内存大小。 | 高说明系统有较多脏页等待写回,可能在高 I/O 环境下堆积。 | 当系统空闲或写回线程运行时会将其写回磁盘。 |
\Memory\Standby Cache Reserve Bytes | Standby Cache 中,标记为“Reserve”优先级的内存页字节数。 | 对应中等优先级缓存,可快速复用。 | Standby Cache 是已加载但暂未被进程使用的缓存页面,划分成多个优先级。 |
\Memory\Standby Cache Normal Priority Bytes | Standby Cache 中,标记为“Normal”优先级的字节数。 | 与 Reserve、Core 优先级做区分,帮助细分缓存占用。 | Normal 一般是默认优先级,可被系统回收以供其他请求使用。 |
\Memory\Standby Cache Core Bytes | Standby Cache 中,标记为“Core”优先级(最高)的字节数。 | 通常用来保存最常被再次访问的数据,不易被回收。 | 如果此值过大,可能会占用其他更紧急需求的内存空间。 |
\Memory\Long-Term Average Standby Cache Lifetime (s) | Standby Cache 中的页面在被回收前的平均停留时长(秒)。 | 越高表示缓存页面驻留时间久,说明可能命中率高或系统缺乏回收压力。 | 可辅助分析缓存效率及系统内存回收机制的积极程度。 |
补充说明
- 页面错误(Page Fault)需要区分软错误与硬错误
- 软错误(Soft Fault):所需页面已在物理内存的其他地方或缓存中,仅需更新页表映射。
- 硬错误(Hard Fault):必须从磁盘读取页面或将页面写出到磁盘。 因此,
\Memory\Page Faults/sec
指标高并不一定意味着大量磁盘 I/O,需要结合\Memory\Pages/sec
、\Memory\Page Reads/sec
、\Memory\Page Writes/sec
等进一步判断。
- 可用内存(Available Memory)与提交内存(Committed Memory)概念不同
- Available Bytes / MBytes:当前仍然空闲、可被立即分配的物理内存。
- Committed Bytes:已分配给进程(或内核)使用,需要物理内存或页面文件做保证。 若
Committed Bytes
接近Commit Limit
,系统会面临内存压力或触发 “Out of Memory” 机制。
- 系统缓存(File System Cache)有助于提高文件 I/O 性能
- 如果缓存命中率低(
\Memory\Cache Faults/sec
高),则频繁访问的新数据会导致更多磁盘读取。 - 过度占用也会导致应用进程可用内存变少,引发更多换页。
- 内核池(Paged Pool / Nonpaged Pool)和驱动内存
- Paged Pool 可交换到磁盘,Nonpaged Pool 常驻物理内存。
- 非分页池(Nonpaged Pool)若持续增长过大,会快速挤占可用内存。
- 需警惕驱动或内核对象的内存泄漏。
- Standby Cache
- Standby Cache 中的页面已读入内存但暂未被任何进程锁定使用,下次访问无需从磁盘读取。
- 分成多个优先级(Core、Normal、Reserve),优先级越高越不易被回收。
\Memory\Long-Term Average Standby Cache Lifetime (s)
可评估页面在缓存中的平均驻留时间,判断缓存策略效果。
通过上表和这些补充说明,可更好地理解和运用 Windows PerfMon 中 “Memory” 对象的各种计数器,方便在系统或应用层面进行内存相关的故障排查与性能优化。
2