kswapd 是什么
kswapd0(每个 NUMA 节点一个)是内核的内存回收线程:当某个 zone 的空闲页降到低水位时被唤醒,扫描 LRU 链表回收页缓存与可换出的匿名页,回到高水位后停止。它属于后台异步回收,正常状态下 CPU 占用很低;如果它长期占用可观 CPU,说明内存压力持续存在,需要判断是工作集超出内存、缓存膨胀,还是水位设置让回收发生得过于频繁。
基本信息
| 线程形态 | kswapd0,每 NUMA 节点一个(多节点会看到多个) |
|---|---|
| 观察命令 | ps -eo pid,pcpu,psr,comm | grep kswapd |
| 回收计数 | /proc/vmstat 的 pgscan_kswapd 与 pgsteal_kswapd |
| 压力视图 | /proc/pressure/memory |
| 水位参考 | /proc/zoneinfo 的 min/low/high |
| 同类线程 | kcompactd 负责内存整理,职责与回收不同 |
典型使用场景
- 判断内存是否长期吃紧:kswapd 持续占 CPU 且回收计数快速增长
- 区分后台回收与直接回收:后者发生在分配路径上,对延迟影响更大
- 排查缓存膨胀造成的反复回收:结合 workingset_refault 看是否在做无用功
- 核对水位参数是否过于激进:调大水位会让回收更早、更频繁发生
- 与 PSI 联合量化内存压力对业务停顿的实际贡献
采样与判读
采样与判读
ps -eo pid,pcpu,psr,comm | grep kswapd # 回收线程的 CPU 占用与所在核
ps -o pid,ni,comm -C kswapd0 # 确认其 nice 值,理解它与业务线程的抢占关系
grep -E 'pgscan_kswapd|pgsteal_kswapd|pgscan_direct|pgsteal_direct' /proc/vmstat # 后台与直接回收计数
cat /proc/pressure/memory # 内存压力视图,判断停顿比例
awk '/Node/{n=$2} /pages free|low|high/{print n, $0}' /proc/zoneinfo | head # 各节点空闲页与水位
ps -eo pid,pcpu,comm --sort=-pcpu | head # 先排除其他高 CPU 进程的干扰关联指标
| 指标 | 含义 | 判读要点 |
|---|---|---|
| kswapd CPU | 后台回收占用的算力 | 长期偏高说明回收是常态而非常态事件 |
| pgscan_kswapd | 后台扫描页数(累计) | 增速反映回收工作量 |
| pgsteal_kswapd | 后台成功回收页数(累计) | 与扫描量之比反映效率 |
| pgscan_direct | 直接回收扫描页数 | 增长比后台回收更值得警惕 |
| memory some/full | 内存停顿比例 | full 持续增长说明已影响全局 |
调大水位参数只会让回收更早、更频繁地发生,并不能减少内存需求。应先确认工作集是否真的超出物理内存,或页缓存是否被反复回收,再考虑动参数。
在多 NUMA 节点的机器上要分节点看:单个节点的空闲页长期偏低就足以持续唤醒该节点的回收线程,而整机汇总数据可能看起来还很宽松。