linux内存回收不是靠“配一个参数”就能搞定的,而是要根据实际负载类型,组合调整vm.vfs_cache_pressure、vm.swappiness、vm.min_free_kbytes和脏页相关参数,并配合观察/proc/meminfo和slabtop -o才能真正起效;其中vm.vfs_cache_pressure控制内核回收inode/dentry缓存的倾向,默认100表示公平回收,小内存云主机或redis/nginx建议设150–200,高并发文件服务可降至50–80,临时生效用sysctl -w,永久生效需写入/etc/sysctl.d/并执行sysctl --system。

直接说结论:Linux内存回收不是靠“配一个参数”就能搞定的,而是要根据实际负载类型,组合调整 vm.vfs_cache_pressure、vm.swappiness、vm.min_free_kbytes 和脏页相关参数(如 vm.dirty_ratio),并配合观察 /proc/meminfo 和 slabtop -o 才能真正起效。
怎么调 vm.vfs_cache_pressure 控制 inode/dentry 回收倾向
这个参数决定内核在内存紧张时,是优先甩掉文件路径缓存(dentry)、元数据(inode),还是保留它们给 page cache 让步。它不控制“频率”,只改回收权重。
- 默认值
100:对 page cache 和 dentry/inode 一视同仁 - 小内存云主机或 Redis/Nginx 类服务:设为
150~200,避免 dentry 积压吃光可用内存 - 高并发静态文件服务(如 CDN 节点):可降到
50~80,多留点路径缓存加速open()、stat() - 临时生效:
sysctl -w vm.vfs_cache_pressure=180 - 永久生效:写入
/etc/sysctl.d/99-vfs.conf,再执行sysctl --system(注意不是sysctl -p)
为什么 vm.swappiness 不能盲目设为 0
设成 0 并不等于“完全禁用 swap”,而是让内核只在内存彻底耗尽时才考虑换出匿名页——但这时往往已经触发 OOM Killer 了。尤其在 fork-heavy 场景(如某些 Python Web 服务、Redis RDB),swappiness=0 反而会让 OOM 更早降临。
- SSD 机器建议设
1~10,兼顾响应与稳定性 - 数据库服务(PostgreSQL/MySQL)推荐
10~20,避免 buffer pool 被挤占 - 容器环境需确认是否支持:运行
sysctl -w vm.swappiness=10,若报Permission denied,说明被 namespace 隔离或内核编译时禁用了该功能 - 查是否生效别只看命令输出,要跑
sysctl vm.swappiness或读/proc/sys/vm/swappiness
怎么避免直接内存回收(direct reclaim)卡住业务
直接回收是同步阻塞式的,一旦触发,当前进程会挂起等回收完成。它通常发生在空闲内存跌破 vm.min_free_kbytes 且 kswapd 来不及响应时。
-
vm.min_free_kbytes必须设合理:太小(如默认几 MB)会导致频繁 direct reclaim;太大(如设成 2GB)又浪费内存。经验公式是总内存 GB 数 × 4096 KB,32GB 机器可设131072 - 脏页参数要匹配磁盘能力:SSD 可设
vm.dirty_ratio=30、vm.dirty_background_ratio=10;机械盘建议更低(如15和5),防止 writeback 堵死 - 观察是否真在发生 direct reclaim:
grep "pgpgin\|pgpgout\|pgmajfault" /proc/vmstat,结合slabtop -o看dentry是否持续高位 - 不要只调单一参数——比如只拉高
vm.vfs_cache_pressure却忽略min_free_kbytes,可能反而加剧 direct reclaim 频次
为什么改完 /etc/sysctl.conf 经常不生效
这不是配置写错了,而是加载机制和权限限制没理清。
-
sysctl -p只读/etc/sysctl.conf,不会加载/etc/sysctl.d/下的文件;要用sysctl --system才行 - 等号前后不能有空格:
vm.swappiness = 10是错的,必须是vm.swappiness=10 - 容器里多数
vm.*参数不可写,Kubernetes 需显式声明securityContext.sysctls,且仅限白名单项 - 云主机(如阿里云 ECS)可能锁定关键参数,
sysctl -w成功返回不代表真的生效,一定要验证运行时值
真正难的不是知道该设哪个值,而是得看清 slab 缓存里 dentry 和 inode 占了多少、page cache 是否被挤到快清空、swap activity 是否异常升高——这些信号比任何“推荐值”都更真实。调参后不盯 /proc/meminfo 和 slabtop,等于蒙眼开车。











