memory-reclaim

理解内核内存回收:水位、kswapd、直接回收与 OOM

补充说明

内存回收发生在空闲页低于水位时:kswapd 在后台回收,分配路径在压力大时进入直接回收(direct reclaim),仍不能满足就触发 OOM killer。回收对象主要是文件页、匿名页(需要 swap)和可回收 slab;page cache 与 tmpfs 的记账方式不同。

常用示例

# 查看内存压力(some 表示至少一个任务被拖慢;文件不存在说明内核未启用 CONFIG_PSI)
cat /proc/pressure/memory

# 查看直接回收与 kswapd 扫描量:direct 持续增长说明分配路径在受苦
grep -E 'pgscan_(direct|kswapd)|pgsteal|allocstall|oom_kill' /proc/vmstat

# 查看各 zone 的水位和空闲页
grep -E 'Node [0-9]+, zone|pages free|^ +min |^ +low |^ +high ' /proc/zoneinfo

# 查看可回收 slab 占用
sudo slabtop -o -s c | head -20

# 查看 cgroup 的内存压力、回收和 OOM 计数(v2)
cat /sys/fs/cgroup/<path>/memory.pressure
grep -E 'pgscan|pgsteal|workingset' /sys/fs/cgroup/<path>/memory.stat
cat /sys/fs/cgroup/<path>/memory.events

# 主动回收 1G(cgroup v2,5.19+;先确认内核支持该文件)
echo 1G | sudo tee /sys/fs/cgroup/<path>/memory.reclaim

# 强制输出一次内存信息到 dmesg(需 sysrq 开启)
echo m | sudo tee /proc/sysrq-trigger

echo m > /proc/sysrq-trigger 只是 dump 内存状态,不是触发回收,也不会杀进程;线上操作前确认 kernel.sysrq 设置。

易错点与排错

读完自测

  1. free 显示内存很少,为什么系统可能仍然健康?
  2. pgscan_direct 持续增长意味着什么?
  3. memory.high 和 memory.max 在回收行为上有什么区别?
答案
  1. page cache 和可回收 slab 可以在压力下释放,健康与否要看 MemAvailable、直接回收计数和 PSI,而不是单看 free。
  2. 分配路径已无法靠后台 kswapd 满足,进程自己进入直接回收,通常伴随延迟抖动和系统 CPU 时间升高。
  3. memory.high 触发节流式回收,可能造成延迟但不一定杀进程;memory.max 是硬上限,回收失败后触发 cgroup OOM。

相关条目