Swap
本文档提供了 GNU/Linux 上 Swap 空间和分页的介绍。它涵盖了 Swap 分区和 Swap 文件的创建与激活。
- Linux 将其物理 RAM(随机存取存储器)划分为称为页的内存块。Swap 是一个将内存页复制到硬盘上预先配置的空间(称为 Swap 空间)的过程,以便释放该内存页。物理内存和 Swap 空间的总和是可用的虚拟内存量。
Swap 的支持由 Linux 内核和来自 util-linux 包的用户空间实用工具提供。
交换空间
Swap 空间可以采用磁盘分区或文件的形式。用户可以在安装过程中或之后根据需要随时创建 Swap 空间。Swap 空间可用于两种目的:将虚拟内存扩展到已安装的物理内存(RAM)之外,以及支持 磁盘休眠。
是否通过 Swap 扩展虚拟内存是有益的,取决于已安装的物理内存量。如果物理内存量不足以运行所有期望的程序,那么启用 Swap *可能*是有益的。这可以避免 内存不足的情况,在这种情况下,Linux 内核 OOM 杀手机制会通过终止进程来自动尝试释放内存。要将虚拟内存量增加到所需水平,请添加必要的 Swap 空间差值(或更多)。
当内存不足时使用 Swap 的最大缺点是其较低的性能,请参阅 #性能 部分。因此,启用 Swap 是个人偏好问题:有些人宁愿程序被终止也不愿启用 Swap,而有些人则宁愿启用 Swap 并在物理内存耗尽时系统变慢。
要检查 Swap 状态,请使用
$ swapon --show
或者显示物理内存和 Swap 使用情况
$ free -h
Swap 分区
可以使用大多数 GNU/Linux 分区工具创建一个 Swap 分区。Swap 分区在 GPT 上使用分区类型 GUID 0657FD6D-A4AB-43C4-84E5-0933C84B4F4F(对于 gdisk 为 0657FD6D-A4AB-43C4-84E5-0933C84B4F4F 类型 GUID,对于 gdisk 为 8200 类型,对于 fdisk 为 swap 类型)进行标识,在 MBR 上使用类型 ID 82。
要将分区设置为 Linux Swap 区域,请使用 mkswap(8) 命令。例如
# mkswap /dev/sdxy
启用设备进行分页
# swapon /dev/sdxy
有关选项语法,请参阅 swapon(8)。
启动时启用
要在启动时启用 Swap 分区,请执行以下操作之一:
- 使用 systemd#GPT 分区自动挂载
- 或在
/etc/fstab中添加一个条目。例如UUID=device_UUID none swap defaults 0 0
- 其中
device_UUID是 Swap 空间的 UUID。
有关文件语法,请参阅 fstab,有关挂载,请参阅 systemd#systemd.mount - 挂载。
禁用 Swap
要停用特定的 Swap 空间
# swapoff /dev/sdxy
或者使用 -a 选项停用所有 Swap 空间。
由于 Swap 由 systemd 管理,它将在下次系统启动时再次激活。要永久禁用已检测到的 Swap 空间的自动激活,请运行 systemctl --type swap 以找到负责的 .swap 单元并对其进行 掩码。
Swap 文件
作为创建整个分区的替代方案,Swap 文件提供了即时更改其大小的能力,并且更容易完全删除。如果磁盘空间有限(例如,一个尺寸适中的 SSD),这可能尤其可取。
| 文件系统 | 支持 Swap 文件 |
|---|---|
| Bcachefs | 否 |
| Btrfs | 是 |
| F2FS | 是 |
| ext4 | 是 |
| JFS | 是 |
| NILFS2 | 否 |
| NTFS3 | 是 |
| ReiserFS | 是 |
| XFS | 是 |
| ZFS | 否 |
Swap 文件创建
使用 mkswap(8) 创建您选择大小的 Swap 文件(有关建议,请参阅 Partitioning#Swap)。例如,创建一个 4 GiB 的 Swap 文件
# mkswap -U clear --size 4G --file /swapfile
激活 Swap 文件
# swapon /swapfile
最后,编辑 fstab 配置以添加 Swap 文件的条目
/etc/fstab
/swapfile none swap defaults 0 0
作为 fstab 的替代方案,可以创建 Swap 单元(请参阅 systemd.swap(5))
/etc/systemd/system/swapfile.swap
[Swap] What=/swapfile [Install] WantedBy=swap.target
执行 daemon-reload 并 启用 swapfile.swap。
有关更多信息,请参阅 fstab#Usage。
Swap 文件移除
要移除 Swap 文件,必须先将其关闭,然后才能移除
# swapoff /swapfile # rm -f /swapfile
最后,从 /etc/fstab 中移除相应的条目。
Swap 加密
请参阅 dm-crypt/Swap 加密。
性能
Swap 操作通常比直接访问 RAM 中的数据慢得多。然而,完全禁用 Swap 以提高性能有时反而会导致性能下降。如果可用的物理内存不足以容纳所有内容,则不 Swap 出任何内容会为文件系统缓存留下更少的内存,导致更频繁和代价高昂的磁盘使用。
可以调整 Swap 值以帮助提高性能
Swappiness
当内存使用量达到一定阈值时,内核会开始查看活动内存,看看可以释放什么。文件数据可以被写回文件系统(如果已更改),然后稍后重新加载;其他数据必须被写入 Swap 才能被卸载。
Swappiness sysctl 参数表示内核倾向于写入 Swap 而不是文件。它可以取 0 到 200 之间的值(Linux < 5.8 时最大为 100);默认值为 60。较低的值会导致内核倾向于释放打开的文件,较高的值会导致内核尝试使用 Swap 空间,值为 100 表示 IO 成本被假定相等。
要检查当前的 swappiness 值
$ sysctl vm.swappiness
或者,可以读取文件 /proc/sys/vm/swappiness 来获取原始整数值。
要临时设置 swappiness 值
# sysctl -w vm.swappiness=35
要永久设置 swappiness 值,请创建一个 sysctl.d(5) 配置文件。例如
/etc/sysctl.d/99-swappiness.conf
vm.swappiness = 35
要让 引导加载程序在加载内核时设置 swappiness,请添加一个 内核参数,例如 sysctl.vm.swappiness=35。
选择不同 swappiness 值的原因可能包括
- 降低 swappiness 已被建议用于桌面响应性。理由是,由于大部分可感知的性能(响应性)取决于程序响应用户输入的响应速度,因此匿名页(程序内存)应保留在 RAM 中,并优先释放打开的文件,即使这会牺牲一些*实际*性能。
- 最低合理的 swappiness 是 1,因为 swappiness 为 0 会导致对匿名页逐出的极端偏见,阻止它们被扫描以进行回收或 Swap,除非在内存竞争最极端的情况下。通常不希望不回收真正未使用的匿名页。
- 当 Swap 的 IO 成本等于或低于从文件读取的成本时,(按定义)需要更高的 swappiness 值(100 或更高)。这可能发生在 Swap 不由磁盘支持的情况下,尤其是在 zram 的情况下。当 Swap IO 被拦截/缓存到成本较低的机制(如 zswap)时,也可能发生这种情况。
VFS 缓存压力
另一个影响 Swap 性能的 sysctl 参数是 vm.vfs_cache_pressure,它控制内核回收用于缓存 VFS 缓存的内存的倾向,相对于 pagecache 和 swap。增加此值会提高 VFS 缓存被回收的速率。有关其功能的更多信息,请参阅 Linux 内核文档。
默认值为 100,这表明文件系统缓存与其他缓存的重要性大致相等,因此它们应该以大致相等的权重被回收。在桌面上,有人认为 文件系统缓存比其他缓存更重要,因为文件系统浏览时间比其他缓存对操作延迟(可感知的响应性)影响更大,因此建议值为 50。另一方面,当 VFS 缓存持有大量不再被访问的小文件的元数据时,建议使用更高的值。有关调整此参数的更多信息,请参阅 OpenSUSE 调优指南(该指南建议进行实验并通过 slaptop 检查缓存类型)。
优先级
如果您有一个以上的 Swap 文件或 Swap 分区,您应该考虑为每个 Swap 区域分配一个优先级值(0 到 32767)。系统将优先使用优先级较高的 Swap 区域,然后再使用优先级较低的 Swap 区域。例如,如果您有一个较快的磁盘和一个较慢的磁盘,请为位于最快设备上的 Swap 区域分配较高的优先级。可以在 fstab 中通过 pri 参数分配优先级
UUID=f9fe0b69-a280-415d-a03a-a32752370dee none swap defaults,pri=100 0 0 UUID=d7eb6062-01c8-4367-ac1d-3bf1167de8bb none swap defaults,pri=10 0 0
或通过 swapon 的 --priority 参数
# swapon --priority 100 /dev/sda1
如果两个或更多区域具有相同的最高优先级,则它们之间会以轮循方式分配页面。
条带化
没有必要为了 Swap 性能原因而使用 RAID。内核本身可以在多个设备上对 Swap 进行条带化,如果您在 /etc/fstab 文件中为它们分配了相同的优先级。有关详细信息,请参阅 The Software-RAID HOWTO。
Discard (又名 trim)
RAM 中的压缩块设备
请参阅 Improving performance#Swap on zram or zswap。
仅将 Swap 空间用于休眠
如果您只需要 Swap 作为休眠镜像存储空间,那么您可以使用 zswap 并禁用其回写功能,这样就不会有常规 Swap 使用产生的磁盘写入。请参阅 Power management/Suspend and hibernate#禁用 zswap 回写以仅将 Swap 空间用于休眠。