交换
本页面介绍了 GNU/Linux 上的交换空间和分页。它涵盖了交换分区和交换文件的创建与激活。
- Linux 将其物理 RAM(随机存取存储器)划分为称为页面的内存块。交换是将内存页面复制到硬盘上预配置的空间(称为交换空间)的过程,以释放该内存页面。物理内存和交换空间的组合大小是可用的虚拟内存量。
对交换的支持由 Linux 内核和 util-linux 软件包中的用户空间实用程序提供。
交换空间
交换空间可以采用磁盘分区或文件的形式。用户可以在安装期间或之后任何需要的时候创建交换空间。交换空间可以用于两个目的:将虚拟内存扩展到超出已安装的物理内存(RAM),以及用于挂起到磁盘支持。
是否使用交换来扩展虚拟内存是否有益取决于已安装的物理内存量。如果物理内存量小于运行所有所需程序所需的内存量,那么启用交换可能是有益的。这避免了内存不足的情况,在这种情况下,Linux 内核 OOM killer 机制将自动尝试通过杀死进程来释放内存。为了将虚拟内存量增加到所需的量,请添加必要的差额(或更多)作为交换空间。
当内存不足时使用交换的最大缺点是其较低的性能,请参见#性能部分。因此,启用交换是个人偏好的问题:有些人喜欢程序被杀死而不是启用交换,而另一些人则喜欢启用交换以及在物理内存耗尽时系统速度变慢。
要检查交换状态,请使用
$ swapon --show
或者显示物理内存以及交换使用情况
$ free -h
交换分区
可以使用大多数 GNU/Linux 分区工具创建交换分区。交换分区由 GPT 上的分区类型 GUID 0657FD6D-A4AB-43C4-84E5-0933C84B4F4F
(gdisk 的 8200
类型,fdisk 的 swap
类型)和 MBR 上的类型 ID 82
指定。
要将分区设置为 Linux 交换区,请使用 mkswap(8) 命令。例如
# mkswap /dev/sdxy
要启用设备进行分页
# swapon /dev/sdxy
有关选项语法,请参见 swapon(8)。
启动时启用
要在启动时启用交换分区,可以
- 使用 systemd#GPT 分区自动挂载
- 或将条目添加到
/etc/fstab
。例如UUID=device_UUID none swap defaults 0 0
- 其中
device_UUID
是交换空间的 UUID。
有关文件语法,请参见 fstab 和 systemd#systemd.mount - 挂载。
禁用交换
要停用特定的交换空间
# swapoff /dev/sdxy
或者使用 -a
开关停用所有交换空间。
由于交换由 systemd 管理,因此它将在下次系统启动时再次激活。要永久禁用自动激活检测到的交换空间,请运行 systemctl --type swap
以查找负责的 .swap 单元并屏蔽它。
交换文件
作为创建整个分区的替代方案,交换文件提供了动态更改其大小的能力,并且更容易完全删除。如果磁盘空间有限(例如,适度大小的 SSD),这可能尤其理想。
文件系统 | 支持交换文件 |
---|---|
Bcachefs | 否 |
Btrfs | 是 |
F2FS | 是 |
ext4 | 是 |
JFS | 是 |
NILFS2 | 否 |
NTFS3 | 是 |
ReiserFS | 是 |
XFS | 是 |
ZFS | 否 |
创建交换文件
使用 mkswap(8) 创建您选择大小的交换文件(有关建议,请参见 分区#交换)。例如,创建 4 GiB 交换文件
# mkswap -U clear --size 4G --file /swapfile
激活交换文件
# swapon /swapfile
最后,编辑 fstab 配置文件以添加交换文件的条目
/etc/fstab
/swapfile none swap defaults 0 0
有关更多信息,请参见 fstab#用法。
移除交换文件
要移除交换文件,必须先将其关闭,然后才能移除
# swapoff /swapfile # rm -f /swapfile
最后,从 /etc/fstab
中移除相关条目。
交换加密
参见 dm-crypt/交换加密。
性能
交换操作通常比直接访问 RAM 中的数据慢得多。但是,完全禁用交换以提高性能有时会导致性能下降。如果物理内存不足以容纳所有内容,则不交换任何内容会使文件系统缓存可用的内存更少,从而导致更频繁和代价更高的磁盘使用。
可以调整交换值以帮助提高性能
Swappiness(交换性)
当内存使用率达到某个阈值时,内核开始查看活动内存,看看可以释放什么。文件数据可以写入文件系统(如果已更改)、卸载并在以后重新加载;其他数据必须先写入交换空间才能卸载。
swappiness sysctl 参数表示内核对写入交换空间而不是文件的偏好。它的值可以在 0 到 200 之间(如果 Linux < 5.8,则最大值为 100);默认值为 60。低值导致内核倾向于释放打开的文件,高值导致内核尝试使用交换空间,值为 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
。
要测试并了解为什么这可能有效,请查看 本文。有关更近期的反驳论点,请参阅 本文。
VFS 缓存压力
另一个影响交换性能的 sysctl 参数是 vm.vfs_cache_pressure
,它控制内核回收用于缓存 VFS 缓存的内存的趋势,而不是页面缓存和交换空间。增加此值会提高 VFS 缓存被回收的速率[1]。有关更多信息,请参见 Linux 内核文档。
优先级
如果您有多个交换文件或交换分区,则应考虑为每个交换区分配优先级值(0 到 32767)。系统将优先使用优先级较高的交换区,然后再使用优先级较低的交换区。例如,如果您有更快的磁盘和更慢的磁盘,请为位于最快设备上的交换区分配更高的优先级。可以通过 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
如果两个或多个区域具有相同的优先级,并且它是可用的最高优先级,则页面将在它们之间以轮循方式分配。
条带化
出于交换性能的原因,没有必要使用 RAID。如果您只是在 /etc/fstab
文件中为多个设备赋予相同的优先级,则内核本身可以对多个设备进行条带化交换。有关详细信息,请参阅 Software-RAID HOWTO。
Discard(又名 trim)
参见 固态硬盘#交换。
RAM 中的压缩块设备
仅将交换空间用于休眠
如果您只需要交换作为休眠映像存储空间,那么您可以使用 zswap 并禁用其回写,以便常规交换使用不会产生磁盘写入。请参阅 电源管理/挂起和休眠#禁用 zswap 回写以仅将交换空间用于休眠。