什么时候该用 Swap?一篇讲清楚

2026-06-08  |  Linux · 运维

先讲个真实的故事

我有一台 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 给当前活跃的进程。

打个生活化的比方:

没有 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

关注这几个指标:

另一个有用的命令——看 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

fallocatedd 更快,因为它是直接分配块而不是逐字节写。如果没有 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:

对于小内存服务器,建议保持默认的 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 的随机猎杀。