Linux 服务器出现内存占用持续偏高,或者进程被 OOM Killer 杀掉,不少人的第一反应是加内存条或者调应用的启动参数。实际上,在扩容物理内存之前,可以先确认一下当前 swap 配置和内存压力。Swap 不会让系统变快,它只是给物理内存不够时留一条后路,让进程有机会继续运行而不是直接被杀掉。这篇文章的适用对象是短期内无法扩容内存、需要临时用磁盘空间支撑内存容量的服务器。生产环境配置 swap 前,需要先想清楚业务对磁盘读写和延迟的容忍度,因为 swap 本身可能拖慢性能。
先别急着改配置
看到内存不足报告后,先别急着敲 fallocate 或 mkswap。检查顺序通常是:先看 free 和 swap 的现状,再看哪些进程占用内存最多,最后看系统日志里有没有出现 oom 或者内存回收的痕迹。用 free -h 可以确认总内存、已用内存、缓存和 swap 使用量;用 top -o %MEM 或 ps aux --sort=-%mem 可以定位占用最高的进程。如果内存主要被缓存吃掉,swap 使用量很低,那并不一定需要配置新的 swap。如果 swap 已满并且频繁触发回收,才需要考虑调整。
决定 Swap 大小和位置的几条参考
swap 大小没有唯一标准。传统经验是物理内存的 1 到 2 倍,但那是针对早期配置较低的场景。现在服务器内存动辄几十 GB,照搬这个倍数会创建非常大的交换文件,反而占满磁盘。比较常见的做法是:如果内存不超过 4GB,swap 可以设为内存的 2 倍;4GB 到 16GB 之间,可以按内存的 1 到 1.5 倍设置;超过 16GB,可以按 8GB 到 16GB 设置,具体取决于业务是否需要休眠或转储。上述建议只是经验值,不是强制标准。还要看磁盘剩余空间和 I/O 性能。如果磁盘原本压力就大,swap 反而容易变成瓶颈。
swap 可以放在独立分区上,也可以使用交换文件。后者便于调整大小,也容易删除,适合临时扩容。云服务器如果数据盘是持久化盘,注意写入量大的操作可能影响磁盘寿命,但磁盘寿命损耗通常小于业务中断的影响。
用交换文件的方式创建 Swap
以交换文件为主,操作路径比较直接。先确认磁盘空间足够,然后选择一个路径,例如 /var/swapfile。创建指定大小的文件,推荐用 dd 而不是 fallocate,因为 fallocate 在某些文件系统上会创建带空洞的文件,可能导致部分情况下的性能问题。例如要创建 4GB 的 swap 文件,用 dd if=/dev/zero of=/var/swapfile bs=1M count=4096。如果内存较大,这个命令会耗时,可以换成 bs=1M count=4096 或者根据磁盘速度等待。
创建完后执行 chmod 600 /var/swapfile,防止普通用户读取敏感内存数据。然后 mkswap /var/swapfile 格式化,swapon /var/swapfile 启用。这几步完成后,用 free -h 或者 swapon --show 查看 swap 是否已经生效。
写入 fstab 并检查启动顺序
如果希望重启后 swap 自动挂载,需要在 /etc/fstab 里添加一行。注意先备份原文件。添加的内容通常是:
/var/swapfile none swap sw 0 0
保存后用 mount -a 检查语法是否正确。更稳妥的做法是执行 swapoff -a 再 swapon -a,确保所有 swap 配置都能正常激活。这里有一个常见问题:如果 fstab 中的 uuid 写错,系统启动时可能进入维护模式。所以编辑完要仔细核对设备路径或 uuid,不能凭记忆敲。
Swappiness 调整:不要直接抄参数
很多教程会让设 vm.swappiness=10 或 20。swappiness 这个参数控制内核使用 swap 的倾向,默认通常是 60。如果内存充足、只是偶尔有突发峰值,可以适当降低到 20~30,让内核更倾向保留物理内存中的页面。但要注意,swappiness 太小可能会让内核在内存压力较大时更频繁地扫描内存,反而增加 CPU 开销。改成 0 也不意味着完全不用 swap,只是降低使用概率。具体值需要结合访问模式观察,而不是照搬一个固定数字。
调整方式为临时修改 /proc/sys/vm/swappiness,例如 echo 20 > /proc/sys/vm/swappiness,立即生效但不保留。要永久生效,在 /etc/sysctl.conf 或 /etc/sysctl.d/99-swap.conf 里写 vm.swappiness=20,然后用 sysctl -p 加载。改这个参数前,最好先记录当前值和一段时间内的内存使用趋势,避免改完不确定是否有用。
改完后看这几个信号
swap 配置完成并不是终点,需要观察几个信号确认效果。第一,free -h 中的 swap used 是否还在持续增长且不回落。第二,vmstat 1 里的 si 和 so 数值,si 表示从磁盘换入内存的页面量,so 表示换出到磁盘的页面量。如果 si/so 持续很大,说明系统在频繁换页,CPU 和磁盘都会受影响,这时单纯调大 swap 已经不能解决根本问题。第三,cat /proc/meminfo 里的 SwapFree 和 SwapTotal 可以用来确认总量。
另外还需要警惕另一个极端:swap 配置过大,可能让一个内存泄漏的进程把磁盘空间吃满,而不是被 OOM Killer 及时终止。所以有些长时间运行的服务,如果希望出现内存异常时快速失败而不是拖垮整个系统,反而需要保守设置 swap 或者配合 cgroup 限制。这也说明,swap 是溢出现场的备胎,不是性能优化工具。
如果配置后系统频繁卡顿,优先排查进程的内存分配循环和读取模式,而不是反复调 swap。回滚操作可以直接把 /etc/fstab 里的那行删掉,然后执行 swapoff /var/swapfile,删除文件即可。上述排查路径足够清晰。