暗色模式

Linux 交换空间:从 swap 文件创建到 swappiness 调优

技术教程
2026-08-13
5
0
本文要点
  • swap(交换空间)是内存不足时的「兜底仓库」:内存放不下的数据先换出到磁盘,避免系统被 OOM 杀掉
  • 查看现状三件套:free -h 看内存与交换用量、swapon --show 看交换设备、/proc/sys/vm/swappiness 看交换倾向
  • 新增 swap 文件四步:fallocate 预分配 → chmod 600 收紧权限 → mkswap 初始化 → swapon 启用
  • 持久化:把 /swapfile none swap sw 0 0 写入 /etc/fstab,重启后自动挂载
  • vm.swappiness 控制系统使用交换的积极程度(默认 60,服务器常调到 10 以减少磁盘写入)
  • 所有命令均在 Ubuntu 24.04(内核 6.8)上真实执行验证

什么是交换空间(swap)

内存(RAM)是服务器最贵的资源之一,一旦耗尽,Linux 会触发 OOM Killer 随机挑选进程杀掉,数据库、Web 服务这些核心进程往往就是受害者。swap(交换空间) 就是为此准备的「兜底仓库」:当物理内存不足时,内核会把暂时不活跃的内存页面换出(swap out)到磁盘上的交换空间,腾出内存给活跃进程;等需要时再换回(swap in)。

注意:swap 是磁盘,速度远慢于内存。它只能缓解内存不足、避免直接宕机,不能替代物理内存——如果长期处于高频换入换出(swap 抖动),正确的做法是加内存条或给应用限流。

swap 有两种形态:

形态优点缺点
swap 分区(swap partition)性能略好、无文件系统开销分区大小固定,扩容需动分区表
swap 文件(swap file)无需重分区、可随时增删改大小受文件系统与页表开销影响,性能略逊

现代 Linux 发行版里两者都很常见。云服务器上swap 文件更灵活:不用重新分区,用 fallocate 建一个文件就能用。Ubuntu 还常用 zram(内存压缩交换)来提升内存利用率,后面会看到。

查看当前的交换空间状态

动手前先摸清现状。三件套命令:

# 1. 内存与交换的整体用量
free -h

# 2. 当前启用的所有交换设备/文件
swapon --show

# 3. 系统使用交换的积极程度(0~100,默认 60)
cat /proc/sys/vm/swappiness

在演示服务器上实际执行,结果如下图:

查看内存与交换空间现状

图中可以看到这台 Ubuntu 24.04 的典型情况:

  • free -h:物理内存 1.8Gi,而 Swap 显示 3.0Gi——说明系统已经在用交换空间;
  • swapon --show:真正在用的交换来源有两个——/tmp/opencode/swapfile(2G 的 swap 文件)和 /dev/zram1(1024M 的 zram 内存压缩交换);
  • swappiness 为默认值 60

swapon --show 是查看交换设备的标准命令(老用法 swapon -s 输出的 Filename/Type/Size/Used/Priority 信息一致)。Type 一列能直接分辨出 file(文件)还是 partition(分区/块设备),排查时很有用。

创建一个 swap 文件

没有现成 swap,或者想扩充,最稳妥的方式就是加一个 swap 文件。完整流程分四步:

# 1. 预分配 512M 空间(fallocate 比 dd 快得多,且稀疏文件更省磁盘)
fallocate -l 512M /swapfile

# 2. 收紧权限——swap 文件里可能残留敏感数据,只允许 root 读写
chmod 600 /swapfile

# 3. 初始化为交换空间
mkswap /swapfile

# 4. 立即启用
swapon /swapfile

把这四步串起来执行一遍,并验证结果:

创建并启用 swap 文件

看执行输出:

  • mkswap 输出 Setting up swapspace version 1, size = 512 MiB,并打印了一个 UUID每次执行 UUID 都不同,这是随机生成的,用来在 /etc/fstab 里唯一定位);
  • swapon --show 里多了一行 /swapfile file 512M——新 swap 已生效;
  • free -h 的 Swap 总量从 3.0Gi 涨到了 3.5Gi(2G 原文件 + 1G zram + 512M 新文件)。
想扩容已有的 swap 文件时,需要先 swapoff 再重建:删除 → 用更大的 fallocate 重新创建 → mkswapswapon。swap 文件不支持原地 resize。

为什么先 chmod 600

swap 文件里可能存有密码、密钥等内存中未被及时清理的数据,权限必须收紧为仅 root 可读写。mkswap 检测到权限过宽时也会警告 insecure permissions。这一步不能省。

开机自动挂载:写入 /etc/fstab

swapon 只对当前运行生效,重启后就丢了。要让 swap 文件开机自动启用,需要写入 /etc/fstab

echo '/swapfile none swap sw 0 0' >> /etc/fstab

fstab 的列含义依次是:设备/UUID → 挂载点 → 文件系统类型 → 挂载选项 → dump 备份标志 → fsck 检查顺序。对 swap 行来说,挂载点写 none、类型写 swap、选项 sw、后面两个 0 即可。

更稳妥的写法是用 UUID 定位:mkswap 输出的 UUID 也可以用在 fstab 里,例如
UUID=659f8d70-1c95-4bab-bfa1-22ed9b060d27 none swap sw 0 0
相比路径,UUID 在磁盘设备号变化时(比如换了硬盘)不会失效。

写入后顺手验证两件事:确认 fstab 内容无误,同时把 swappiness 调成更适合服务器的值:

cat /etc/fstab
sysctl vm.swappiness=10
cat /proc/sys/vm/swappiness

写入 fstab 持久化并调低 swappiness

图中 fstab 已经包含新增的 /swapfile none swap sw 0 0 一行,vm.swappiness 也被临时调整为 10

调整 swappiness:平衡内存与磁盘

swappiness 取值范围 0~100,含义是内核倾向于把内存页换出到 swap 的积极程度

行为
0极少使用 swap,尽量把数据留在内存(新内核 6.8 起语义略有变化,0 表示「禁止换出」)
10~30服务器常用区间:内存吃紧时才开始换出,减少磁盘写入
60默认值,桌面/通用场景的折中
100非常积极换出,适合大量空闲内存页需要回收的场景

临时调整(重启失效):

sysctl vm.swappiness=10

永久调整(写入 /etc/sysctl.d/,比直接改 /etc/sysctl.conf 更规范):

echo 'vm.swappiness=10' > /etc/sysctl.d/99-swappiness.conf
sysctl -p /etc/sysctl.d/99-swappiness.conf

数据库、缓存类服务建议调低(如 10),避免磁盘频繁写入拖慢性能;而本身大量空闲的机器用默认值即可。

关闭与移除 swap

想移除一个 swap 文件,顺序与创建相反:

# 1. 关闭该 swap(数据会迁回内存,需要内存足够)
swapoff /swapfile

# 2. 从 /etc/fstab 中删除对应行
sed -i '\#/swapfile#d' /etc/fstab

# 3. 删除文件
rm -f /swapfile

# 4. 验证
swapon --show
free -h
sed 里用 # 作定界符是因为路径里有 /,避免转义麻烦。注意操作前确认内存余量足够容纳被换出的数据,否则会 OOM。

常见问题排查

1. fallocate 报错 "fallocate failed: Operation not supported"

某些文件系统(早期 ext3、部分网络文件系统)不支持 fallocate 的预分配。退回 dd 方案:

dd if=/dev/zero of=/swapfile bs=1M count=512

2. swap 文件权限警告 "insecure permissions"

mkswap 会在权限过宽时拒绝或警告。执行 chmod 600 /swapfile 后重新 mkswap 即可。

3. 频繁 swap 抖动(thrashing)

swapon --showUSED 持续接近满、free -h 里 Swap 的 used 持续高位,说明内存真的不够用了。调低 swappiness 只能缓解,根本解法是加内存或限制应用占用(如调小 JVM 堆、MySQL buffer pool)。

4. zram 与 swap 文件并存

Ubuntu 的 zram 也计入 swap,swapon --show 里会看到 partition 类型条目。zram 其实是压缩内存,速度比磁盘 swap 快很多,一般优先级更高(图中 zram1 的 PRIO 100 高于 swapfile 的 -2),系统会优先换出到 zram。两者共存是正常配置,无需处理。

5. 想给某个分区单独指定 swap

swap 分区与文件用法一致,只是把路径换成 /dev/sdXn

mkswap /dev/sdb1
swapon /dev/sdb1

参考资料

发表评论

暂无评论,快来抢沙发吧!