linux没有“页缓存回收阈值”独立开关,实际由min_free_kbytes推导的内存水位线(wmark_min/low/high)决定回收启动时机;调大该值可提前触发kswapd回收,建议设为物理内存1%–3%,并配合dirty_ratio参数防止写密集场景卡死。

Linux 没有“页缓存回收阈值”这个独立可设的开关,真正起作用的是内存水位线(WMARK_*)和触发回收的内核参数组合,直接改 min_free_kbytes 是最有效、最可控的入口。
为什么不能直接设“页缓存回收阈值”
内核不提供类似 pagecache_reclaim_threshold 这样的单一配置项。页面回收由内存压力驱动,而压力判断依赖于 zone 的三个水位线:WMARK_MIN、WMARK_LOW、WMARK_HIGH —— 它们不是用户可直接写入的 sysctl 值,而是由 min_free_kbytes 推导出的运行时变量。
- 改
min_free_kbytes会同步抬高所有水位线,相当于“提前触发回收” - 试图用
drop_caches或调整vfs_cache_pressure只能影响回收倾向或对象类型,不改变回收启动时机 -
vm.vfs_cache_pressure控制的是 inode/dentry 缓存 vs page cache 的回收优先级,不是“多少内存空闲才开始回收”
怎么设置实际生效的回收启动点
核心是调大 min_free_kbytes,让内核更早启动 kswapd 回收。该值单位为 KB,建议按物理内存的 1%–3% 设置(例如 64GB 内存 → 设为 1024000 即约 1GB):
- 查看当前值:
cat /proc/sys/vm/min_free_kbytes - 临时生效:
echo 1024000 > /proc/sys/vm/min_free_kbytes - 永久生效:在
/etc/sysctl.conf中添加vm.min_free_kbytes = 1024000,然后运行sysctl -p - 验证效果:观察
cat /proc/zoneinfo | grep -E "(watermark|free)输出中各 zone 的pages_min是否上升
配合 dirty_ratio 防止写密集场景卡死
仅调高 min_free_kbytes 对纯读场景(如 CDN 缓存服务)足够;但若存在持续写入,脏页堆积可能压垮内存,此时必须同步约束脏页上限:
-
vm.dirty_background_ratio设为 5–10(后台回写启动点),避免脏页静默堆积 -
vm.dirty_ratio设为 15–20(前台阻塞点),防止进程被突然挂起 - 二者必须同时设,且
dirty_ratio > dirty_background_ratio,否则后者失效 - 注意:如果设置了
vm.dirty_background_bytes或vm.dirty_bytes,对应 ratio 参数会被忽略
容易被忽略的细节
回收行为最终取决于每个内存 zone(DMA、Normal、HighMem)的独立水位线,而不是全局内存总量。在 NUMA 或多网卡设备较多的机器上,min_free_kbytes 调得过大可能导致某些 zone 空闲内存远超预期,反而浪费可用内存;调得太小又会让 kswapd 长期处于高频扫描状态。务必用 cat /proc/zoneinfo 查看各 zone 的 pages_min 和当前 free_pages,确认回收确实发生在你期望的时机。











