什么是 Swap
Swap(交换空间)是 Linux 在磁盘上划出的一块区域(可以是独立分区或文件),用于在物理内存(RAM)不足时临时存放部分内存数据。当系统内存紧张时,内核会将一部分暂时不用的内存页从 RAM 移动到 Swap 中,腾出物理内存给活跃进程使用;当这些被移出的数据再次需要时,再从 Swap 读回到内存。这个过程被称为“页面换出”和“页面换入”。
Swap 的工作原理
Linux 内核的内存管理以“页”为基本单位(通常为 4 KB)。当系统需要分配新内存但空闲物理内存不足时,内核会尝试回收内存,手段包括:
- 释放缓存:丢弃干净的页面缓存(如文件缓存),因为数据原本就存在于磁盘上,可以重新读取;
- 换出匿名页:将不活跃的进程堆、栈、共享内存等匿名页写入 Swap 空间,因为这些数据只存在于内存中没有磁盘备份。
是否使用 Swap 以及使用多频繁,主要由一个可调参数 swappiness 控制(/proc/sys/vm/swappiness)。它的取值范围是 0 到 100,反映内核优先回收文件缓存还是优先换出匿名页的倾向。值越低,越倾向于保留匿名页而回收文件缓存;值越高,越积极使用 Swap。默认值通常为 60,对于数据库等场景有时建议调低到 10 甚至 0,以尽量避免将热数据换出。
触发时机
Swap 并不等到物理内存完全耗尽时才开始使用,而是在内存水位线以下时提前换出。内核维护着三个内存阈值:高水位、低水位、最低水位。当空闲内存降到低水位以下时,内核线程 kswapd 会被唤醒,开始异步回收页面,这期间可能产生 Swap 写入。如果内存分配请求非常紧迫,kswapd 来不及回收足够空间,就会触发 直接回收,让当前请求内存的进程亲自去执行页面回收,此时会产生明显的延迟。
用 free -h 命令可以看到 Swap 的总量和使用量。少量、偶发的 Swap 使用是正常的,但如果 Swap 被持续大量占用且伴随频繁换入换出,就说明物理内存已经严重不足。
性能影响
内存的读写速度通常是磁盘的数千倍甚至上万倍(DDR4 约 20-50 GB/s,SATA SSD 约 500 MB/s,HDD 约 100 MB/s),而且内存延迟远低于磁盘。因此,无论 Swap 所在的磁盘是传统机械硬盘还是 SSD,一旦系统开始频繁换入换出,性能都会急剧下降,表现为:
- 单个请求的响应时间变长;
- CPU 大量的时间消耗在等待 I/O 上(
iowait升高); - 负载(load average)上升,整体吞吐量暴跌。
如果 Swap 位于廉价 VPS 的超卖磁盘上,性能退化会更加严重。SSD 虽然顺序读写远快于 HDD,但仍远慢于 RAM,且频繁的 Swap 写入会加速 SSD 的写磨损。
实用建议
- 保留适当的 Swap:即使内存充裕,也建议配置至少 1-2 GB 的 Swap,给系统一个缓冲。对于休眠到磁盘(suspend to disk)的桌面系统,Swap 必须至少和内存一样大。
- 监控 Swap 使用:定期检查
vmstat中的si(swap in)和so(swap out)列,如果这些值持续非零且数值较大,说明存在内存压力,应增加物理内存或优化应用内存使用。 - 按场景调整 swappiness:
- 数据库、缓存服务(如 Redis)等希望尽可能将所有数据保留在内存的场景,可将 swappiness 设为 10-20;
- 桌面系统默认即可;
- 容器环境(Docker)建议设置 swappiness 为较低值或使用内存限制配合。
- 使用现代替代方案:对于内存受限的设备,可以考虑 zram(在内存中创建压缩块设备并用作 Swap),用 CPU 时间换取更多“可用内存”,且避免磁盘 I/O。在嵌入式系统和部分 Linux 发行版中已经成为默认配置。
Swap 本质上是“用磁盘空间换取运行时间”的最后安全网,而不是性能加速器。理想情况下,它应该像灭火器一样长期闲置,一旦被启动,就意味着需要关注系统的内存供给情况。