Linux 交换分区(Swap Partition) 是一块专门划分的磁盘空间,核心作用是作为物理内存的「扩展」 ------ 当物理内存不足时,内核会将物理内存中不活跃的页数据「换出(swap out)」到交换分区;当这些页数据需要被访问时,再将其「换入(swap in)」回物理内存。这种机制也被称为虚拟内存管理,是 Linux 内存管理子系统的重要组成部分。
核心目标
- 扩展内存可用空间:让系统可以运行比物理内存总量更大的程序或更多进程。
- 保证内存资源的高利用率:将不活跃的内存页置换到磁盘,释放物理内存给活跃进程使用。
- 避免 OOM(内存不足) Killer 触发:当物理内存耗尽时,Swap 可以临时缓解内存压力,避免内核直接杀死进程。
典型应用场景
- 物理内存较小的嵌入式系统:通过 Swap 弥补内存不足的问题。
- 运行大内存消耗程序的场景:如数据库、虚拟机、科学计算等,Swap 可作为内存峰值的缓冲。
- 休眠(Hibernation)功能:系统休眠时,会将整个物理内存的内容写入 Swap 分区,开机时再恢复,因此休眠功能要求 Swap 分区大小不小于物理内存。
工作原理
Swap 的核心是内核的 页面置换算法 ,其运作依赖于 Linux 内存管理的「页」机制 ------ 物理内存和 Swap 空间都以 页(通常 4KB) 为单位进行数据交换。
活跃页与不活跃页
内核通过 LRU(最近最少使用)链表 将物理内存中的页分为两类:
- 活跃页(Active List):近期被频繁访问的页,内核会优先保留在物理内存中。
- 不活跃页(Inactive List):近期很少被访问的页,是 Swap 换出的候选对象。
内核会定期扫描 LRU 链表,根据页面的访问频率调整其在活跃 / 不活跃链表之间的位置。
页面换出(Swap Out)
当物理内存使用率达到内核设定的阈值(由 /proc/sys/vm/swappiness 控制)时,内核启动换出流程:
- 选择换出页 :从
Inactive List中挑选符合条件的页,优先选择匿名页(无文件映射的页,如进程栈、堆数据)------ 文件页可直接丢弃,需要时从磁盘文件重新读取,无需换出到 Swap。 - 分配 Swap 空间:内核从 Swap 分区 / 文件中分配一个空闲的 Swap 页槽(slot),记录该页的 Swap 位置(包括 Swap 设备编号和页偏移)。
- 写入数据 :将物理内存页的数据写入 Swap 槽,并更新该页对应的
page结构体,标记为PG_swapbacked,同时记录 Swap 位置信息。 - 释放物理页:将该页从 LRU 链表中移除,标记为空闲,纳入物理内存分配池。
页面换入(Swap In)
当进程访问一个已经被换出到 Swap 的页时,会触发 缺页异常,内核执行换入流程:
- 识别缺页类型 :内核通过
page结构体判断该页是 Swap 换出页,获取其对应的 Swap 位置。 - 分配物理页:从物理内存中分配一个空闲页。
- 读取数据:将 Swap 分区中对应槽的数据读取到新分配的物理页中。
- 更新页表与 LRU :修改进程页表,将虚拟地址映射到新的物理页;将该页加入
Active List,标记为活跃;释放 Swap 槽,使其重新变为空闲。
Swap 的关键内核组件
| 组件 | 作用 |
|---|---|
| swap_info_struct | 描述 Swap 设备 / 文件的元数据,包括大小、空闲页槽数、优先级等 |
| swap_entry_t | 记录页在 Swap 中的位置(设备 ID + 页槽偏移),存储在页表项中 |
| 页面置换算法 | 决定哪些页被换出,Linux 默认使用 LRU-2 或 Multi-Gen LRU(5.18+ 内核) |
| kswapd 内核线程 | 周期性扫描内存,当内存不足时主动触发页面换出,避免系统进入内存紧缺状态 |
Swap 的类型
Linux 支持两种 Swap 形式:Swap 分区 和 Swap 文件,两者功能完全等价,仅创建和管理方式不同。
Swap 分区
- 定义 :一块独立的磁盘分区,格式为
swap类型(fdisk中 ID 为82)。 - 优点:IO 性能略高(无文件系统开销),适合物理磁盘场景。
- 缺点:需要提前划分分区,扩容或缩容需要重新分区,灵活性差。
Swap 文件
- 定义:一个普通的磁盘文件,由内核格式化为 Swap 格式使用。
- 优点:无需划分独立分区,创建和扩容灵活(支持动态增减),适合云服务器、虚拟机等灵活部署场景。
- 缺点:有文件系统的元数据开销,IO 性能略低于 Swap 分区(现代文件系统如 Ext4/XFS 差距极小)。
创建 Swap 分区
步骤 1:划分磁盘分区
使用 fdisk 或 parted 工具划分一个新分区,类型设为 swap(ID=82):
以 /dev/sdb 为例
fdisk /dev/sdb
在 fdisk 交互界面中:
1. 输入 n 创建新分区
2. 输入 t 修改分区类型,输入 82 设为 swap 类型
3. 输入 w 保存分区表
步骤 2:格式化 Swap 分区
使用 mkswap 命令将分区格式化为 Swap 格式:
mkswap /dev/sdb1
步骤 3:启用 Swap 分区
swapon /dev/sdb1
步骤 4:设置开机自动挂载
编辑 /etc/fstab 文件,添加以下内容:
/dev/sdb1 swap swap defaults 0 0
创建 Swap 文件
步骤 1:创建 Swap 文件
使用 dd 命令创建一个指定大小的文件(例如 4GB):
dd if=/dev/zero of=/swapfile bs=1G count=4
步骤 2:设置文件权限
限制 Swap 文件的访问权限,仅 root 可读写:
chmod 600 /swapfile
步骤 3:格式化 Swap 文件
mkswap /swapfile
步骤 4:启用 Swap 文件
swapon /swapfile
步骤 5:设置开机自动挂载
编辑 /etc/fstab 文件:
/swapfile swap swap defaults 0 0
常用 Swap 管理命令
| 命令 | 作用 |
|---|---|
swapon -s |
查看当前启用的 Swap 设备 / 文件信息(大小、已用、优先级) |
swapon /path/to/swap |
启用指定的 Swap 设备 / 文件 |
swapoff /path/to/swap |
关闭指定的 Swap 设备 / 文件 |
cat /proc/swaps |
查看 Swap 详细信息(与 swapon -s 输出一致) |
vmstat -s |
查看内存和 Swap 的统计数据(如换入 / 换出页数) |
Swap 的核心调优参数
Swap 的行为主要通过 /proc/sys/vm/ 下的内核参数调整,最关键的是 swappiness。
swappiness:控制页面换出的倾向
- 定义 :取值范围
0 ~ 100,默认值通常为60(不同发行版略有差异)。 - 含义 :
swappiness = 0:内核尽可能不换出内存页,仅在物理内存耗尽时才使用 Swap。swappiness = 100:内核积极将不活跃页换出到 Swap,最大化物理内存的空闲空间。
- 调优建议 :
- 桌面系统 / 大内存服务器 :设置为
10 ~ 30,减少磁盘 IO 开销,提升响应速度。 - 小内存系统 / 嵌入式设备 :设置为
60 ~ 80,充分利用 Swap 扩展内存。 - 数据库服务器(如 MySQL) :设置为
1,避免数据库缓存页被换出,影响性能。
- 桌面系统 / 大内存服务器 :设置为
vfs_cache_pressure:控制文件缓存的换出倾向
- 定义 :取值范围
0 ~ 100,默认值100。 - 含义 :控制内核回收 页缓存(Page Cache) 的倾向,页缓存是文件系统的磁盘缓存。
- 值越低,内核越倾向于保留页缓存;值越高,越倾向于回收页缓存。
- 调优建议 :对于 IO 密集型场景,可适当降低该值(如
50),提升文件访问速度。
Swap的特点
- Swap 是磁盘级存储 :磁盘 IO 速度远低于物理内存(机械硬盘差距约 1000 倍,SSD 差距约 100 倍),频繁的换入 / 换出会导致系统性能急剧下降,表现为 CPU 等待 IO 时间过长 、进程响应缓慢。
- Swap 是「应急方案」而非「性能方案」:Swap 仅适合缓解内存压力,不能替代物理内存。长期依赖 Swap 运行的系统,应优先扩容物理内存。
- 误区 :「Swap 越大越好」------ Swap 过大会导致内核将大量活跃页换出,反而降低性能。通常建议 Swap 大小为 物理内存的 1~2 倍(休眠功能需等于或大于物理内存)。
- 误区 :「禁用 Swap 能提升性能」------ 对于大内存系统,禁用 Swap 可能导致 OOM Killer 误杀进程;合理配置
swappiness才是最优解。