swap
swap = 内核用于回收匿名页(anonymous pages)的后备存储
它只服务于匿名页:
- 进程堆(heap)
- 栈(stack)
- malloc/new 出来的内存
- JVM / Python / Go runtime 内存
❌ 不直接用于:
- 文件页(page cache)
- 磁盘映射文件(mmap 文件)
| 误解 | 真相 |
|---|---|
| swap 是慢内存 | ❌ |
| swap 能当内存用 | ❌ |
| swap 会拖慢系统 | ❌ (前提是没乱用) |
正确理解:
swap 是 OOM 之前的缓冲区,不是 RAM 的替代品
内核回收顺序(极简版):
内存压力 ↑
↓
回收 page cache
↓
回收 slab
↓
回收匿名页(→ swap)
↓
OOM Killer
👉 没有 swap,匿名页回收这一步直接失败
/dev/sda2 swap swap defaults 0 0
- ✅ 吞吐稳定
- ✅ 不受文件系统影响
- ❌ 灵活性差
适合:
- 裸机数据库
- 物理服务器
/data/swapfile/2G.swap
- ✅ 可动态调整
- ✅ 云主机友好
- ❌ 老内核可能碎片化(新内核已解决)
现代内核(≥ 4.0)完全可用
| 技术 | 本质 |
|---|---|
| zram | 内存里压缩 swap |
| zswap | swap 前压缩层 |
- ✅ 延迟低
- ✅ 减少磁盘 IO
适合:
- 小内存
- VPS
- 桌面
- 内存碎片
- 匿名页长期不访问
- 瞬时峰值
- fork / copy-on-write
- Python / JVM GC 前
swap 使用 ≠ 性能问题
大量 swap in/out 才是问题
vm.swappiness = 0 ~ 200
| 值 | 行为 |
|---|---|
| 0 | 几乎不用 swap (不是完全不用) |
| 1 | 仅作为安全阀 (推荐) |
| 10 | 温和 |
| 60 | 默认 |
| 100+ | 积极 swap |
| 场景 | swappiness |
|---|---|
| 数据库 | 1 |
| 容器宿主机 | 1~5 |
| 通用服务器 | 10 |
| 桌面 | 60 |
| 值 | 行为 |
|---|---|
| 0 | 启发式 (默认) |
| 1 | 允许超额 |
| 2 | 严格限制 |
数据库推荐:
vm.overcommit_memory = 0
防止系统进入“内存抖动”
vm.min_free_kbytes = 1% ~ 3% RAM
小 swap + 极低 swappiness 是最稳方案
原因:
- 避免匿名页分配失败
- 防止 fork / bgwriter 失败
- 防止 OOM 误杀数据库
vm.swappiness = 1
vm.overcommit_memory = 0
swap:
- 4~8GB 即可(不追求使用)
- cgroup OOM ≠ kernel OOM
- container 突发内存不可控
- page cache 竞争严重
没有 swap,OOM 会更早、更狠
推荐:
- swap = 8~16GB
- swappiness = 1
- 严格 memory limit
| 真正原因 | 表现 |
|---|---|
| 内存不足 | 持续 swap in/out |
| swappiness 过高 | 不必要换出 |
| IO 瓶颈 | swap 等待 |
vmstat 1
关注:
si / so是否持续非 0- 不是偶尔出现
- ✅ 内存 ≥ 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 = 给内核一个“缓冲带”,避免瞬时内存压力直接触发 OOM
它解决的是三个问题:
- 匿名页回收失败
- 内存碎片化
- 突发峰值(spike)
| 作用 | 说明 |
|---|---|
| 防 OOM | 极其关键 |
| 内存碎片 | 非常明显 |
| 后台任务 | 有 swap 才能活 |
✅ 建议
- swap = 内存 × 1~2
swappiness = 10~30
❌ 不要禁 swap
| 场景 | swap 价值 |
|---|---|
| Web / API | 明显 |
| Python / Node | 明显 |
| 小型数据库 | 有价值 |
✅ 建议
- swap = 8~16GB
swappiness = 10
这是 swap“有没有意义”的分水岭
| 场景 | 建议 |
|---|---|
| 通用服务器 | 保留小 swap |
| 数据库 | 小 swap |
| 容器宿主机 | 必须有 |
✅ 建议
- swap = 8GB(不是为了用,是为了不 OOM)
swappiness = 1~5
swap 不再是“资源”,而是“保险丝”
| 价值 | 说明 |
|---|---|
| 性能 | 基本无 |
| 稳定性 | 有 |
| 防误杀 | 有 |
✅ 建议
- swap = 4~8GB
swappiness = 1
❌ 不建议完全禁用(除非你非常自信)
绝大多数工作负载已经不需要 swap
| 场景 | 建议 |
|---|---|
| 裸机数据库 | 可禁 |
| 大内存缓存 | 可禁 |
| HPC | 禁 |
❌ 但以下情况例外:
- 容器宿主机
- Kubernetes 节点
- JVM / Python 混合负载
- 有不可控第三方进程
“小 swap + 极低 swappiness” > “完全禁 swap”
-
避免:
- 内存碎片导致
malloc失败 - WAL / shared memory 分配失败
- 内存碎片导致
-
swap 只换出 冷匿名页
-
不会换数据库 buffer(page cache)
✅ 推荐配置
vm.swappiness = 1
vm.overcommit_memory = 0
swap 大小:
- 物理内存 ≤ 64GB:4~8GB
- ≥ 128GB:可不要
没有 swap 的宿主机,更容易“整节点 OOM”
- cgroups OOM ≠ kernel OOM
- container burst 非常常见
- page cache 竞争激烈
✅ 推荐
- swap = 8~16GB(不追求使用)
swappiness = 1- cgroup memory limit 严格
- 内存分配是提前的
- OOM 是最后手段
- 没 swap -> 回收路径更短
- 直接 kill 进程
换句话说:
swap 是 OOM 的“缓冲带”,不是性能工具
如果你的内存峰值不可精确预测 -> 保留 swap 如果你的进程集合不可控 -> 保留 swap 如果你运行的是容器 / JVM / Python -> 保留 swap
swap 不是慢的根源,乱用 swap 才是 真正危险的是:没 swap + 内存估算错误