vm.swappiness过高导致内核过早换出匿名页;水位线设置不当引发回收延迟;脏页堆积阻塞writeback;cgroup v1硬限导致回收滞后。
vm.swappiness 设置过高导致内核过早换出匿名页
Linux 内存回收是否“及时”,首先取决于内核对内存压力的判断逻辑。vm.swappiness 控制的是内核在内存紧张时,倾向于回收文件页(page cache)还是换出匿名页(如进程堆、栈)的倾向值。默认是 60,但若设为 80 或更高,内核会更激进地将匿名页写入 swap,哪怕还有大量可回收的 page cache。
-
vm.swappiness=100:等同于“不区分页类型,能换就换”,容易掩盖真实内存压力,也拖慢回收响应 -
vm.swappiness=1到10更适合物理内存充足、追求低延迟的场景(如数据库服务器) - 查看当前值:
cat /proc/sys/vm/swappiness;临时修改:sysctl vm.swappiness=10
注意:该参数只影响“回收策略倾向”,不决定“是否触发回收”——真正触发回收的是 watermark 水位线。
内存水位线(watermark)设置不合理或被动态抬高
内核通过 min、low、high 三档 watermark 判断何时启动 kswapd 回收或直接阻塞分配。如果这些水位线被意外抬高(例如因大量 hugepage 预留、cgroup memory limit 过紧、或 /proc/sys/vm/lowmem_reserve_ratio 配置失当),会导致:
- kswapd 长时间不唤醒,直到内存耗尽才触发直接回收(direct reclaim),造成卡顿
- 即使有空闲 page cache,系统也拒绝分配,因为未跌破
low水位
验证方式:cat /proc/zoneinfo | grep -A 5 "pages free",关注各 zone 的 min 和 pages free 差值。若差值长期
脏页(dirty page)堆积阻塞 writeback 进程
当应用持续写文件且未显式 fsync(),或 vm.dirty_ratio 设得过大(如 80),会导致大量脏页滞留在内存中。此时即使有足够空闲内存,kswapd 也无法回收这些页——它们必须先由 pdflush(旧内核)或 writeback 线程刷盘。
常见现象: