Skip to main content
☘️ Septvean's Documents
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

swap

一、swap 是什么(不要再被“虚拟内存”带偏)

1️⃣ swap 的真实定义

swap = 内核用于回收匿名页(anonymous pages)的后备存储

只服务于匿名页

  • 进程堆(heap)
  • 栈(stack)
  • malloc/new 出来的内存
  • JVM / Python / Go runtime 内存

❌ 不直接用于:

  • 文件页(page cache)
  • 磁盘映射文件(mmap 文件)

2️⃣ swap ≠ 内存扩容

误解 真相
swap 是慢内存
swap 能当内存用
swap 会拖慢系统 ❌ (前提是没乱用)

正确理解:

swap 是 OOM 之前的缓冲区,不是 RAM 的替代品


二、Linux 内存回收路径里 swap 在哪?

内核回收顺序(极简版):

内存压力 ↑
回收 page cache
回收 slab
回收匿名页(→ swap)
OOM Killer

👉 没有 swap,匿名页回收这一步直接失败


三、swap 的三种形式(非常重要)

1️⃣ swap 分区(最稳定)

/dev/sda2   swap   swap   defaults   0 0
  • ✅ 吞吐稳定
  • ✅ 不受文件系统影响
  • ❌ 灵活性差

适合:

  • 裸机数据库
  • 物理服务器

2️⃣ swap 文件(最常用)

/data/swapfile/2G.swap
  • ✅ 可动态调整
  • ✅ 云主机友好
  • ❌ 老内核可能碎片化(新内核已解决)

现代内核(≥ 4.0)完全可用


3️⃣ zram / zswap(压缩 swap)

技术 本质
zram 内存里压缩 swap
zswap swap 前压缩层
  • ✅ 延迟低
  • ✅ 减少磁盘 IO

适合:

  • 小内存
  • VPS
  • 桌面

四、swap 什么时候“真的被用到”?

swap 触发的真实场景

  1. 内存碎片
  2. 匿名页长期不访问
  3. 瞬时峰值
  4. fork / copy-on-write
  5. Python / JVM GC 前

swap 使用 ≠ 性能问题
大量 swap in/out 才是问题


五、核心内核参数(必须掌握)

1️⃣ vm.swappiness(最常被误用)

vm.swappiness = 0 ~ 200
行为
0 几乎不用 swap (不是完全不用)
1 仅作为安全阀 (推荐)
10 温和
60 默认
100+ 积极 swap

推荐值

场景 swappiness
数据库 1
容器宿主机 1~5
通用服务器 10
桌面 60

2️⃣ vm.overcommit_memory(和 swap 强相关)

行为
0 启发式 (默认)
1 允许超额
2 严格限制

数据库推荐:

vm.overcommit_memory = 0

3️⃣ vm.min_free_kbytes(间接影响 swap)

防止系统进入“内存抖动”

vm.min_free_kbytes = 1% ~ 3% RAM

六、swap 与数据库(重点)

PostgreSQL / MySQL 官方共识

小 swap + 极低 swappiness 是最稳方案

原因:

  • 避免匿名页分配失败
  • 防止 fork / bgwriter 失败
  • 防止 OOM 误杀数据库

推荐组合

vm.swappiness = 1
vm.overcommit_memory = 0

swap:

  • 4~8GB 即可(不追求使用)

七、swap 与容器 / Kubernetes

为什么 K8S 不建议禁 swap?

  • cgroup OOM ≠ kernel OOM
  • container 突发内存不可控
  • page cache 竞争严重

没有 swap,OOM 会更早、更狠

推荐:

  • swap = 8~16GB
  • swappiness = 1
  • 严格 memory limit

八、swap 的性能真相

swap 慢的根本原因不是 swap

真正原因 表现
内存不足 持续 swap in/out
swappiness 过高 不必要换出
IO 瓶颈 swap 等待

正确判断是否“有问题”

vmstat 1

关注:

  • si / so 是否持续非 0
  • 不是偶尔出现

九、关于“禁用 swap”的真话

什么时候可以禁?

  • ✅ 内存 ≥ 128GB
  • ✅ 单一、可控负载
  • ✅ 无容器 / 无 JVM
  • ✅ 明确 OOM 策略

什么时候别禁?

  • ❌ 容器宿主机
  • ❌ 多语言运行时
  • ❌ 第三方程序
  • ❌ 云主机

十、你可以直接照抄的工程模板

通用服务器

vm.swappiness = 10
vm.overcommit_memory = 0
vm.min_free_kbytes = 262144

数据库服务器

vm.swappiness = 1
vm.overcommit_memory = 0

容器宿主机

vm.swappiness = 1
vm.overcommit_memory = 0

总结

swap 是内核回收匿名页的退路,不是内存的替代
没有 swap,系统更容易 OOM;乱用 swap,系统才会慢


补充

Swap(交换空间)是物理内存(RAM)不足时的磁盘缓存,二者通过“借用”关系协同工作以防止系统崩溃,用于休眠或缓解突发内存压力。

Swap 与物理内存的依赖关系

  • 功能互补:Swap 本质是磁盘上的一个区域,当物理内存被占满时,操作系统将不常用的数据移动到 Swap,从而释放物理内存给紧急程序使用。
  • 性能权衡:硬盘(Swap)的速度远慢于 RAM,大量使用 Swap 会导致系统运行非常缓慢(系统响应迟钝)。
  • 休眠支持:在笔记本电脑中,要实现“休眠到硬盘”(Suspend to Disk),Swap 空间通常需要等于或大于物理内存。

特殊场景

  • 服务器:如果经常爆内存,应优先增加物理内存,而非依赖 Swap
  • SSD 硬盘:在使用 SSD 时,过大的 Swap 交换可能会加快硬盘寿命衰减,应尽量保证足够大的物理内存

总而言之,Swap 不是越大越好,其合理大小依赖于物理内存的大小和实际工作负载。


一句话结论(先记住)

内存 ≤ 32GB:swap 有现实意义
内存 ≥ 64GB:swap 更多是“安全阀”,而不是性能工具
内存 ≥ 128GB:大多数生产场景可以不要 swap

但 –

👉 数据库 / JVM / 容器宿主机是例外,需要单独看


核心本质(先把认知掰正)

swap 的本质不是“扩容内存”

swap = 给内核一个“缓冲带”,避免瞬时内存压力直接触发 OOM

它解决的是三个问题:

  1. 匿名页回收失败
  2. 内存碎片化
  3. 突发峰值(spike)

按内存规模给你一份“是否有意义”的判断表

🟢 ≤ 8GB 内存(非常有意义)

作用 说明
防 OOM 极其关键
内存碎片 非常明显
后台任务 有 swap 才能活

建议

  • swap = 内存 × 1~2
  • swappiness = 10~30

❌ 不要禁 swap


🟢 16GB 内存(仍然有意义)

场景 swap 价值
Web / API 明显
Python / Node 明显
小型数据库 有价值

建议

  • swap = 8~16GB
  • swappiness = 10

🟡 32GB 内存(临界点)

这是 swap“有没有意义”的分水岭

场景 建议
通用服务器 保留小 swap
数据库 小 swap
容器宿主机 必须有

建议

  • swap = 8GB(不是为了用,是为了不 OOM)
  • swappiness = 1~5

🟠 64GB 内存(安全阀级别)

swap 不再是“资源”,而是“保险丝”

价值 说明
性能 基本无
稳定性
防误杀

建议

  • swap = 4~8GB
  • swappiness = 1

❌ 不建议完全禁用(除非你非常自信)


🔴 ≥ 128GB 内存(多数场景可不要)

绝大多数工作负载已经不需要 swap

场景 建议
裸机数据库 可禁
大内存缓存 可禁
HPC

但以下情况例外

  • 容器宿主机
  • Kubernetes 节点
  • JVM / Python 混合负载
  • 有不可控第三方进程

特殊场景:数据库(你这个用户非常关键)

PostgreSQL / MySQL 的真实建议

“小 swap + 极低 swappiness” > “完全禁 swap”

为什么?

  • 避免:

    • 内存碎片导致 malloc 失败
    • WAL / shared memory 分配失败
  • swap 只换出 冷匿名页

  • 不会换数据库 buffer(page cache)

推荐配置

vm.swappiness = 1
vm.overcommit_memory = 0

swap 大小:

  • 物理内存 ≤ 64GB:4~8GB
  • ≥ 128GB:可不要

Kubernetes / 容器宿主机(重点)

没有 swap 的宿主机,更容易“整节点 OOM”

原因

  • cgroups OOM ≠ kernel OOM
  • container burst 非常常见
  • page cache 竞争激烈

推荐

  • swap = 8~16GB(不追求使用)
  • swappiness = 1
  • cgroup memory limit 严格

为什么“禁 swap”反而容易翻车?

真实机制

  1. 内存分配是提前的
  2. OOM 是最后手段
  3. 没 swap -> 回收路径更短
  4. 直接 kill 进程

换句话说:

swap 是 OOM 的“缓冲带”,不是性能工具


一个“工程级判断公式”

如果你的内存峰值不可精确预测 -> 保留 swap 如果你的进程集合不可控 -> 保留 swap 如果你运行的是容器 / JVM / Python -> 保留 swap


最后的关键一句话(请记住)

swap 不是慢的根源,乱用 swap 才是 真正危险的是:没 swap + 内存估算错误