Linux中swap使用率高但available内存充足,根本原因是内核启用overcommit且vm.swappiness偏高,导致内核主动换出闲置匿名页,而available仅表示可立即分配的物理内存,并不阻止swap行为。

这其实是 Linux 内存管理中一个常见但容易误解的现象:swap 使用率高,但 free -h 显示的 available 内存却很充足。根本原因往往不是物理内存真的不足,而是内核启用了 overcommit,且工作负载触发了内核的 swap 倾向性策略(尤其是 vm.swappiness 设置偏高 + 有大量匿名页被回收)。
为什么 available 多,swap 还在用?
Linux 的 available 是内核估算的、**可立即用于新进程的物理内存总量**,它包含:未使用的 page cache、可快速回收的 slab、以及部分可换出的匿名页(只要 swap 空间就绪)。也就是说,“available 高”只说明系统当前不缺内存来启动新任务,不代表内核不会主动把某些匿名页(如堆内存)换出到 swap——尤其当 vm.swappiness > 0 且内存压力信号(如 pgpgout、pgmajfault 上升)出现时。
在 overcommit 模式下(默认 vm.overcommit_memory = 0),内核允许进程申请远超物理内存+swap 总和的虚拟内存。只要实际没全用上,就不会 OOM;但一旦这些匿名页被真正写入并随后闲置,内核可能优先 swap 出去腾出物理页给更活跃的 page cache 或新分配,导致 swap 使用率持续偏高。
检查是否真存在 overcommit 风险
运行以下命令确认当前 overcommit 策略和使用情况:
-
cat /proc/sys/vm/overcommit_memory:值为 0(启发式)、1(总是允许)、2(严格限制);生产环境建议用 2 + 合理设vm.overcommit_ratio -
grep -i "commit" /proc/meminfo:看Committed_AS是否接近或超过CommitLimit(仅当 overcommit_memory=2 时有意义) -
cat /proc/sys/vm/swappiness:默认 60,值越高越倾向 swap;对数据库、低延迟服务建议调至 1~10
定位哪些进程在“悄悄”占 swap
free -h 看不到具体谁在用 swap,需结合以下方式:
-
sudo swapon --show=NAME,TYPE,SIZE,USED,PRI:确认 swap 设备状态 -
sudo awk '/Swap:/ {print $3}' /proc/*/status 2>/dev/null | sort -n | tail -10:粗略查看 top 10 占 swap 的进程(单位 KB) -
sudo smaps_rollup(需 kernel ≥ 4.17)或遍历/proc/PID/smaps中Swap:行:精确统计每个进程的 swap 使用量 -
sudo cat /sys/fs/cgroup/memory/memory.memsw.usage_in_bytes(若启用 memsw):cgroup 级别总 memory+swap 消耗
实用缓解建议
- 降低
vm.swappiness至 10 或更低(sysctl -w vm.swappiness=10),抑制非必要 swap - 确认是否真需要 swap:纯计算型服务、内存充足且无休眠需求时,可考虑禁用 swap(
swapoff -a),避免干扰内存调度 - 若必须保留 swap,使用 zram 或 zswap:压缩内存页而非写盘,显著降低 I/O 开销和延迟
- 检查应用是否存在内存泄漏或缓存滥用(如 JVM -Xmx 过大但实际负载低),导致大量匿名页长期驻留又不活跃
- 升级内核至 5.0+:引入
vm.reclaim_swappiness(替代 swappiness),更好区分 file-backed 和 anon page 回收倾向
关键点在于:swap 使用率 ≠ 内存瓶颈。重点看 available 是否稳定、pgpgin/pgpgout 是否持续飙升、pgmajfault 是否增长——这些比 swap% 更能反映真实压力。不复杂但容易忽略。










