linux中不存在“虚拟内存低水位”,实际是物理内存zone的wmark_low水位线触发kswapd异步回收;可调参数仅有vm.min_free_kbytes(决定min基线并推导low)和vm.watermark_scale_factor(调节low与min间距),均须通过sysctl设置,/proc/zoneinfo仅用于查看。

Linux 中“虚拟内存低水位”这个说法并不准确——内核管理的是物理内存的空闲页水位线(WMARK_LOW),它触发的是后台页面回收(kswapd),而非虚拟内存本身。所谓“低水位触发后台回收”,实际是指当某个内存 zone 的空闲页数(pages_free)低于其 low 水位时,kswapd 被唤醒并开始异步回收。
真正可调、且直接影响 low 水位的参数只有两个,且必须通过 sysctl 接口设置:
注意:不能直接写 /proc/zoneinfo 或 /proc/sys/vm/low_watermark,它们是只读统计项。
1. 用 vm.min_free_kbytes 设定全局最低保障空闲内存
这是最核心、最常用的调整方式。它定义了系统**必须保留的最小空闲内存(KB)**,内核据此按各 zone 容量比例,自动推算出每个 zone 的 `min`、`low`、`high` 水位(单位:页)。- 增大该值 → 所有 zone 的
low水位同步抬高 → kswapd 更早被唤醒,回收更积极 - 减小该值 →
low下移 → kswapd 启动延迟,但可用内存变多(风险:易触达min导致直接回收卡顿)
例如,设为 512MB:
sudo sysctl -w vm.min_free_kbytes=524288
生效后,立即运行:
cat /proc/zoneinfo | awk '/Node.*zone/{n=$0}/low.*:/&&n{print n,$0}' | grep -o "low [0-9]\+"
即可看到各 zone 的 low 值已更新(单位:页,×4KB ≈ MB)。
2. 用 vm.watermark_scale_factor 微调 low 与 min 的间距
它不改变 `min` 绝对值,只控制 `low − min` 和 `high − low` 的相对宽度(默认值 10,对应约总内存的 0.1%)。- 设为较小值(如 5)→
low更靠近min→ kswapd 活动窗口变窄,启动晚、停得快,回收更“节制” - 设为较大值(如 200)→
low显著高于min→ kswapd 提前介入,回收行为更平缓,适合大内存服务器避免抖动
例如:
sudo sysctl -w vm.watermark_scale_factor=150
⚠️ 注意:该值需配合 min_free_kbytes 使用才有意义;单独调整效果有限。
3. 验证 low 水位是否合理
不要只看 `free -h` 的 `available`,真实压力信号在 `/proc/zoneinfo`:- 查当前
pages_free和pages_low差值:awk '/pages_free/ {f=$3} /pages_low/ {l=$3; print "free-low =", f-l}' /proc/zoneinfo | head -n1 - 若常为负数或频繁接近 0 →
low过高,预留过多,有效内存被锁死 - 若
free长期略高于low、但pgpgin/pgpgout持续飙升 →low过低,kswapd 启动太晚,已逼近min
建议结合 vmstat 1 观察 sr(swap in)、pgscan_kswapd 等字段,再决定是否调整。
4. 调整后持久化与注意事项
- 将配置写入 `/etc/sysctl.conf` 以重启生效: ```bash echo 'vm.min_free_kbytes = 524288' | sudo tee -a /etc/sysctl.conf echo 'vm.watermark_scale_factor = 150' | sudo tee -a /etc/sysctl.conf sudo sysctl -p ``` - NUMA 系统中,各 node 的 zone 水位独立计算,需整体评估;若某 node 长期 free 偏低,可能需检查 `numa_zonelist_order` 或绑定进程到合适 node - 不推荐盲目设 `min_free_kbytes > 总内存的 3%`,否则可能显著压缩应用可用内存空间不复杂但容易忽略:水位线是 per-zone 的,而 min_free_kbytes 是全局锚点——调准它,就调准了整个回收节奏的起点。











