直接回收是什么
直接回收发生在内存分配路径上:当某次分配发现水位不足,进程自己必须同步扫描并回收页,回收完成之前无法继续执行。这就是 allocstall 计数增长常与延迟毛刺同时出现的原因——它把回收成本直接加到了业务线程上。与之相对的是 kswapd 的后台回收,由内核线程异步完成,通常不会阻塞业务。
基本信息
| 核心计数 | grep allocstall /proc/vmstat(新内核按 zone 细分) |
|---|---|
| 配套计数 | pgscan_direct、pgsteal_direct |
| 追踪手段 | perf record -e 'vmscan:*' -ag(需 root 与 perf 支持) |
| 关联指标 | /proc/pressure/memory 的 full 行、业务延迟毛刺 |
| 常见诱因 | 水位不足、高阶分配(大页/驱动 DMA)、NUMA 本地节点紧张 |
| 影响面 | 直接体现为分配线程的停顿,对延迟敏感服务危害最大 |
典型使用场景
- 排查业务延迟毛刺:把 allocstall 增量与延迟曲线放在同一时间轴对齐
- 判断是否该抬高水位或增加内存:持续增长说明分配经常走同步回收
- NUMA 机器上定位本地节点紧张:整机空闲充裕也会频繁触发直接回收
- 驱动或大页相关的分配问题:高阶分配更依赖连续页,失败路径更长
- 容量评估:把直接回收的发生频率作为扩容的量化信号之一
确认与追踪
确认与追踪
grep allocstall /proc/vmstat # 分配路径上的直接回收次数(可能按 zone 细分)
sleep 60 # 隔一分钟再采一次,比较差值才能判断是否持续发生
sudo perf record -e 'vmscan:*' -ag -- sleep 10 # 采集回收相关事件
sudo perf report --stdio | head -20 # 查看直接回收的调用来源
grep -E 'pgscan_direct|pgsteal_direct' /proc/vmstat # 直接回收的规模与回收量
cat /proc/pressure/memory # full 行增长与直接回收高度相关
sar -B 1 5 # 看 pgscand/s 与 %vmeff,判断直接回收的速率与效率关联指标
| 项目 | 含义 | 判读要点 |
|---|---|---|
| allocstall | 分配时被迫直接回收的次数 | 增量频率决定影响程度 |
| pgscan_direct | 直接回收扫描的页数 | 反映工作量大小 |
| pgsteal_direct | 直接回收释放的页数 | 与扫描量之比反映回收效率 |
| %vmeff(sar) | 整体回收效率 | 偏低说明该扩容而不是调参 |
| memory full | 全局停顿比例 | 持续增长说明影响已扩散 |
分配路径上的回收代价直接落在业务线程上,因此比后台回收更值得警惕。观察时要按 NUMA 节点看:本地节点不足时,即使整机空闲内存充裕也可能频繁触发直接回收。
偶发一次直接回收并不可怕,关键是频率与业务延迟的相关性。把计数增量与监控中的延迟曲线叠加,如果两者同步出现尖峰,才算建立了因果证据。