什么时候该用 Swap?一篇讲清楚
先讲个真实的故事
我有一台 2GB 内存的云服务器,上面跑了两个 Docker 容器——一个 QQ 机器人(NapCat,内置完整 QQ 客户端),一个 AI 聊天机器人(AstrBot)。平时相安无事,但只要我一启动 Claude Code CLI,过不了多久服务器就会"卡死"——进程中断、连接断掉、有时候甚至 SSH 都进不去。
排查之后发现,凶手是 OOM Killer(Linux 内核的内存不足杀手)。2GB 的 RAM 被两个容器吃掉将近 600MB,系统和其他服务再占一点,Claude Code 作为一个 Node.js 进程,对话上下文一长,内存就飙上去了。RAM 吃满那一刻,内核别无选择,只能随机毙掉一个进程来保命。
解决办法出奇简单——加了一个 2GB 的 Swap 文件。世界清静了。
Swap 是什么?
用一句话说:Swap 是 Linux 的虚拟内存,当物理内存(RAM)不够用时,系统把一部分暂时不活跃的数据从内存搬到硬盘上,腾出 RAM 给当前活跃的进程。
打个生活化的比方:
- RAM = 你的办公桌面。伸手就能拿到东西,速度飞快,但面积有限。
- Swap = 桌边的文件柜。东西放进去拿出来会慢一些,但好歹有个地方放,不至于直接把文件扔进垃圾桶。
没有 Swap 时,桌面堆满就真的满了——你只能把某个文件揉成团扔掉(OOM Kill)。有 Swap 时,你可以把暂时不看的文件先收进柜子里,桌面就腾出空间了。
什么情况下应该开 Swap?
1. 小内存服务器(强烈推荐)
≤ 2GB 内存的 VPS 或云服务器,跑个 Web 服务、数据库、Docker,内存非常容易吃紧。Swap 是性价比最高的兜底方案。
2. 内存使用波动大的场景
你的服务平时内存够用,但偶尔会有突发高峰——比如定时任务、CI/CD 构建、同时来了多个请求。Swap 帮你吸收这些毛刺,避免"平时好好的,突然就崩了"。
3. 跑多个服务的"小钢炮"服务器
像我那台机器,同时跑 QQ 机器人 + AI 机器人 + 偶尔跑 CLI 工具,各服务之间会争抢内存。Swap 给它们一个缓冲区。
4. 没有 K8s / 自动扩容的裸机
如果你不是在云上按需扩缩容的那种架构,Swap 是最简单的人寿保险。
什么情况下不该用 Swap?
1. Redis / Elasticsearch / 数据库等对延迟敏感的服务
这些服务严重依赖内存速度,如果数据被换出到 Swap,再读回来就是灾难级性能下降。对于这类服务,应该加内存而不是开 Swap。事实上很多 DBA 会让你把 vm.swappiness 调到很低甚至关掉 Swap,就是为了防止这种"Swap 颠簸"。
2. 你的内存已经足够
如果一台 64GB 内存的服务器平时只用 10GB,开 Swap 没什么意义——它几乎永远不会被用到,只会白白占硬盘空间。
3. 用 HDD 机械硬盘、且系统已经在高 IO 负载下
Swap 本质是读写磁盘。如果你的硬盘已经是瓶颈了,再加上 Swap 的读写,会让情况更糟。SSD 上这个问题小很多。
4. 你想用 Swap "代替" 加内存
这是最大的误区。Swap 是缓冲垫,不是替代品。如果你的服务日常就需要 4GB 内存,而你只有 2GB RAM + 2GB Swap,那么系统会陷入一种叫做"Swap 颠簸"(thrashing)的状态——内核不停地把数据在 RAM 和硬盘之间搬来搬去,CPU 全耗在搬运上,系统卡到你连 SSH 都打不开。Swap 是用来兜底的,不是让你可以不升配的。
怎么判断要不要开 Swap?
一条命令看当前状态:
free -h
关注这几个指标:
available列:如果你经常看到这个数低于 200-300MB,且机器时不时"卡一下",那 Swap 大概率能帮到你。Swap行全为零:你当前没有 Swap,内存一旦满了就是硬着陆。
另一个有用的命令——看 OOM Killer 的"杀人记录":
dmesg | grep -iE 'oom|out of memory|killed'
如果能看到记录,说明机器曾经因为内存不足杀过进程,这就是明确的信号。
实操:Linux 上创建和启用 Swap
第一步:看看还剩多少磁盘空间
df -h /
Swap 文件要放在有足够空间的分区上。一般建议 Swap 大小等于 RAM 大小(内存小时比如 2GB RAM → 2GB Swap),或者 RAM 的一半(大内存时)。
第二步:创建一个 Swap 文件
sudo fallocate -l 2G /swapfile
fallocate 比 dd 更快,因为它是直接分配块而不是逐字节写。如果没有 fallocate,可以用:
sudo dd if=/dev/zero of=/swapfile bs=1M count=2048
第三步:设权限(必须)
sudo chmod 600 /swapfile
Swap 文件能直接读取内存里的敏感数据(密码、密钥等),所以必须设为 600,只有 root 可读写。
第四步:格式化为 Swap 格式
sudo mkswap /swapfile
第五步:启用
sudo swapon /swapfile
第六步:验证
free -h
应该能看到 Swap 行不再是零了。
第七步(关键!):加到 fstab 让重启后自动挂载
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
不加这行的后果:重启之后 Swap 没了,一切归零,你还得手动再来一遍。
调优:控制 Linux 对 Swap 的"侵略性"
vm.swappiness 这个内核参数控制系统多积极地使用 Swap。取值范围 0-100:
0:尽量不用 Swap,内存快用完时才开始用。60(默认值):内存在用掉约 40% 后就开始使用 Swap。100:非常激进地使用 Swap。
对于小内存服务器,建议保持默认的 60 或适当调低到 20-30:
# 查看当前值
cat /proc/sys/vm/swappiness
# 临时修改
sudo sysctl vm.swappiness=30
# 永久修改
echo 'vm.swappiness=30' | sudo tee -a /etc/sysctl.conf
如果你跑 Redis / 数据库,且只是想让 Swap 当"终极兜底",可以设得更低(比如 5-10)。
总结
| 场景 | 建议 |
|---|---|
| 小内存 VPS(≤2GB)、跑多服务 | 开,Swap = RAM 大小 |
| 内存足够(≥8GB)、日常余量充足 | 不需要 |
| 跑 Redis / ES / 数据库 | 内存先给够,Swap 设为应急兜底(swappiness 调极低) |
| 服务日常内存需求 > 物理 RAM | 别用 Swap 硬撑,升级硬件 |
| 服务器出现过 OOM Kill | 开 Swap,同时排查哪个进程在狂吃内存 |
说到底,Swap 是缓冲垫,不是扩容方案。它的作用是——在你真正加内存之前,别让你的服务死于 OOM Killer 的随机猎杀。