首页/系统/Linux 内核与性能调优速查/回收效率指标 pgscan/pgsteal
内存与 OOM58 条

回收效率指标 pgscan/pgsteal

pgscan 是扫描页数、pgsteal 是成功回收页数;两者比值反映回收效率,效率低说明扫描的多是不可回收或高频访问页。

两个计数是什么

pgscan 是内核扫描过的页数,pgsteal 是其中被真正回收(释放)的页数,二者共同刻画回收效率:比值接近 1 说明扫到的页基本都能回收,成本低收益高;比值很低说明扫描了大量正在活跃使用的页,回收代价高却释放不了多少内存——这通常意味着活跃工作集已经接近或超过可用物理内存。计数按后台(kswapd)与直接(direct)两条路径分别统计。

基本信息

读取方式grep -E 'pgscan|pgsteal' /proc/vmstat
数据性质全部为累计值,必须两次采样求差
路径区分pgscan_kswapd/pgsteal_kswapd(后台)与 *_direct(分配路径)
效率口径Δpgsteal/Δpgscan,或直接看 sar -B 的 %vmeff
配套指标workingset_refault(热页被回收后又读回)、pgmajfault
版本差异新内核会按 zone 与阶数细分出更多字段

典型使用场景

  • 判断回收是否有效:效率持续偏低说明可回收页越来越少,扩内存比调参更对症
  • 区分压力层级:direct 路径增长直接影响业务延迟,kswapd 属后台代价
  • 识别无用功:workingset_refault 高说明刚回收的热页马上又要读回
  • 压测观察:记录不同内存占用下回收效率的变化,找到性能拐点
  • 为扩容决策提供量化依据,而不是仅凭「内存看起来很满」

对比增量

对比增量
grep -E 'pgscan|pgsteal' /proc/vmstat | sort  # 查看全部扫描与回收计数
grep -E 'workingset_refault|pgmajfault' /proc/vmstat  # 配合判断是否在做无用功
sleep 60  # 隔一分钟再采一次:效率 ≈ Δpgsteal / Δpgscan
sar -B 1 5  # 直接给出扫描/回收速率与 %vmeff 回收效率
cat /proc/pressure/memory  # 内存停顿比例,判断是否已影响全局
awk '/^anon|^file/{print}' /sys/fs/cgroup/myapp.slice/memory.stat  # 容器视角看回收对象构成

计数读法

计数含义判读要点
pgscan_kswapd后台回收扫描的页数增速反映后台工作量
pgsteal_kswapd后台成功回收的页数与扫描量共同决定效率
pgscan_direct分配路径上扫描的页数增长说明回收压在业务线程上
pgsteal_direct直接回收释放的页数与效率一起判断收益
workingset_refault热页被回收后又读回的次数偏高说明工作集与内存不匹配
回收效率在 sar -B 里以 %vmeff 直接给出,也可以自己用增量算:Δpgsteal 除以 Δpgscan。效率长期偏低说明可回收的页越来越少,此时增加内存通常比继续调回收参数更有效。
不同内核版本对这两个计数的细分程度不同(是否按 zone、阶数展开)。采集脚本应按字段前缀匹配,而不是写死完整字段名,避免升级后静默取到零值。

易错点

  • 用累计绝对值互相比较:必须换算成同一时间窗的增量,否则结论会随时间漂移
  • 只看扫描量不看回收量:扫描多不代表回收有效,可能全是在扫描活跃页
  • 忽略 direct 与 kswapd 的区别:直接回收发生在业务线程的分配路径上,延迟代价完全不同
  • 不结合 workingset_refault:无法判断是否把马上要用到的页回收掉,属于典型的负收益回收
  • 把字段名写死:内核升级后细分字段变化会导致采集出零值而不报错

数据来源与参考

  • Linux 内核 mm/vmscan.c
  • Linux 内核 Documentation/admin-guide/mm/
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌