本文介绍了GNU/Linux上的交换空间和分页。它将教您如何创建或启用交换分区或交换文件。
以下引用来自于关于 Linux Swap 空间:
- Linux 将物理内存分为内存段,叫做页面。交换是指内存页面被复制到预先设定好的硬盘空间(叫做交换空间)的过程,目的是释放这份内存页面。物理内存和交换空间的总大小是可用的虚拟内存的总量。
swap 支持由 Linux 内核和来自 util-linux包 软件包的用户空间实用程序提供。
交换空间
交换空间可以是磁盘的一个分区,也可以是一个文件。用户可以在安装时或安装后的任何时候创建交换空间。交换空间有两种用途:第一,是将虚拟内存扩大到超过已安装的物理内存(RAM)的容量;第二,是用于 suspend-to-disk 支持。
使用swap扩展您的虚拟内存是否有好处取决于您的物理内存。如果物理内存不足以支撑您日常使用全部的程序的话(体现在日常使用时内存满了导致的卡顿,死机),使用swap也许会对您有些帮助。这样可以避免 out of memory conditions,Linux内核OOM Killer机制将尝试通过杀进程的方式来自动释放内存。如果您想让虚拟内存足够使用,请添加相应的差值(或更多)作为交换空间。
启用交换的最大缺点是性能较低,请参阅:#性能优化。因此,启用swap是个人喜好问题:当物理内存用完时,有些人更喜欢杀死程序而不是启用交换,而另一些人更喜欢启用交换和较慢的系统。
要检查交换空间的状态,使用:
$ 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 - mounting。
关闭交换分区
使用下面的命令关闭交换分区:
# swapoff /dev/sdxy
也可以使用 -a
参数来关闭所有的交换分区。
因为 swap 通过 systemd 管理,因此会在下一次系统启动时再次激活。要永久禁用该特性,运行 systemctl --type swap
来查找 .swap 单元,然后 mask 它。
交换文件
相比于使用一个磁盘分区作为交换空间,使用交换文件可以更方便地随时调整大小或者移除。当磁盘空间有限(例如常规大小的SSD)时,使用交换文件更加理想。
文件系统 | 是否支持交换文件 |
---|---|
Bcachefs | 否 |
Btrfs | 是 |
F2FS | 是 |
ext4 | 是 |
JFS | 是 |
NILFS2 | 否 |
NTFS3 | 是 |
ReiserFS | 是 |
XFS | 是 |
ZFS | 否 |
建立交换文件
使用 mkswap(8) 创建一个由你自己指定大小的交换文件(参见 Partitioning#Swap 获取建议)。例如,创建一个 4 GiB 的交换文件:
# mkswap -U clear --size 4G --file /swapfile
启用交换文件:
# swapon /swapfile
最后,编辑 /etc/fstab
,在为交换文件添加一个条目:
/etc/fstab
/swapfile none swap defaults 0 0
有关更多信息,请参见 fstab#Usage.
删除交换文件
如果要删除一个交换文件,必须先停用它。
作为root运行:
# swapoff /swapfile
然后即可删除它:
# rm -f /swapfile
最后从 /etc/fstab
中删除相关条目
交换加密
性能优化
交换操作通常比直接访问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
要永久设置交换值,请创建sysctl.d(5)配置文件。例如:
/etc/sysctl.d/99-swappiness.conf
vm.swappiness=35
为了让 boot loader 在加载内核时设置交换值,添加一个 kernel parameter,例如 sysctl.vm.swappiness=35
.
要测试和了解这可能起作用的原因,请查看此文章。有关最近的反对意见,请参阅 这篇文章。
VFS 缓存压力
vm.vfs_cache_pressure
是另外一个影响交换性能的 sysctl 参数,这个参数控制内核回收 VFS 缓存的程度,增大数值会增加回收 VFS 缓存的频率[1]。更多信息请阅读 Linux kernel documentation。
优先级
如果你有多个交换文件或交换分区,你应该考虑给它们各自分配一个优先级值(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 指南。
丢弃(即 trim)
在RAM中使用压缩块设备
参见 Improving performance#zram or zswap。
仅将交换空间用于休眠
如果你只需要交换空间作为休眠映像存储空间,那么你可以使用 zswap 并禁用其回写,以便在常规交换使用中没有磁盘写入。参见 Power management/Suspend and hibernate#Disable zswap writeback to use the swap space only for hibernation。