Swap
本文介绍了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 分区工具(例如 fdisk
, cfdisk
) 创建。交换分区在 MBR 中的类型为 82
,在 GPT 中的类型为 0657FD6D-A4AB-43C4-84E5-0933C84B4F4F
。
要将分区设置为Linux交换分区,请使用 mkswap(8) 命令。例如:
# mkswap /dev/sdxy
想要启用一个设备作为交换分区:
# swapon /dev/sdxy
想要启动时自动启用交换分区,添加一个条目到 /etc/fstab
:
UUID=device_UUID none swap defaults 0 0
UUID可以通过以下命令获得:
lsblk -no UUID /dev/sdxy
其中 device_UUID
是交换分区的 UUID 。有关文件语法,请参见 fstab。
通过 Systemd 激活[编辑 | 编辑源代码]
systemd 通过两种机制来激活 swap 分区。两种都是 /usr/lib/systemd/system-generators
内的可执行文件。generators 在启动时运行并为 mounts 创建本地 systemd 单元。第一种机制是通过 systemd-fstab-generator
读取 fstab 来生成单元,包括 swap 单元。 第二种机制是通过 systemd-gpt-auto-generator
检查根磁盘来生成单位。这个机制仅在 GPT 磁盘上运行,并可以根据交换分区的GUID类型对其进行标识。详细信息,请参阅 systemd#GPT partition automounting。
关闭交换分区[编辑 | 编辑源代码]
使用下面的命令关闭交换分区:
# swapoff /dev/sdxy
也可以使用 -a
参数来关闭所有的交换分区。
因为 swap 通过 systemd 管理,因此会在下一次系统启动时再次激活。要永久禁用该特性,运行 systemctl --type swap
来查找 .swap 单元,然后 mask 它。
交换文件[编辑 | 编辑源代码]
相比于使用一个磁盘分区作为交换空间,使用交换文件可以更方便地随时调整大小或者移除。当磁盘空间有限(例如常规大小的SSD)时,使用交换文件更加理想。
建立交换文件[编辑 | 编辑源代码]
使用 dd 去创建一个由你自己指定大小的交换文件。例如,创建一个 512 MiB 的交换文件:
# dd if=/dev/zero of=/swapfile bs=1M count=512 status=progress
为交换文件设置权限(交换文件全局可读是一个巨大的本地漏洞):
# chmod 0600 /swapfile
创建正确大小的文件后,将其格式化用来作为交换文件:
# mkswap -U clear /swapfile
启用交换文件:
# swapon /swapfile
最后,编辑 /etc/fstab
,在为交换文件添加一个条目:
/etc/fstab
/swapfile none swap defaults 0 0
有关更多信息,请参见 fstab#Usage.
删除交换文件[编辑 | 编辑源代码]
如果要删除一个交换文件,必须先停用它。
作为root运行:
# swapoff /swapfile
然后即可删除它:
# rm -f /swapfile
最后从 /etc/fstab
中删除相关条目
在内存中的压缩块设备[编辑 | 编辑源代码]
如果使用了交换文件或分区,默认会支持 zswap。如果使用 zram 内存压缩块设备,就不再需要交换文件或分区。zram 和 zswap 的区别请参考 Improving performance#zram or zswap。
交换加密[编辑 | 编辑源代码]
查看 dm-crypt/交换分区加密。
性能优化[编辑 | 编辑源代码]
交换操作通常比直接访问RAM中的数据慢得多。完全禁用交换以提高性能有时会导致性能下降,因为它会减少VFS缓存的可用内存,从而导致更频繁地使用宝贵的磁盘I/O。
可以调整交换值以提高性能:
交换值(Swappiness)[编辑 | 编辑源代码]
swappiness sysctl 参数代表了内核对于交换空间的喜好(或厌恶)程度。Swappiness 的值可以是 0 到 200 之间 (在Linux内核版本低于5.8时最大值为100),默认值为60。设置这个参数为较低的值会减少内存的交换,从而提升一些系统上的响应度。较高值会导致内核尝试使用交换空间,而值100意味着各IO的喜好(或厌恶)程度相等。众所周知,在许多系统中,在足够的内存上使用较低的值可以提高响应能力。
要查看当前交换值(Swappiness),请执行以下操作:
$ sysctl vm.swappiness
此外,可以读取文件 /sys/fs/cgroup/memory/memory.swappiness
(仅适用于 cgroup v1) 或 /proc/sys/vm/swappiness
以获得原始整数值。
要临时设置交换值(Swappiness),请执行以下操作:
# sysctl -w vm.swappiness=10
要永久设置交换值,请创建sysctl.d(5)配置文件。例如:
/etc/sysctl.d/99-swappiness.conf
vm.swappiness=10
To have the boot loader set swappiness when loading the kernel, add a kernel parameter, e.g. sysctl.vm.swappiness=10
.
要测试和了解这可能起作用的原因,请查看此文章.
VFS 缓存压力[编辑 | 编辑源代码]
vm.vfs_cache_pressure
是另外一个影响交换性能的 sysctl 参数,这个参数控制内核回收 VFS 缓存的程度,增大数值会增加回收 VFS 缓存的频率[1]. 更多信息请阅读 Linux kernel documentation。
优先级[编辑 | 编辑源代码]
如果你有多个交换文件或交换分区,你应该考虑给它们各自分配一个优先级值(0 到 32767)。在使用较低优先级的交换区域之前,系统会优先使用较高优先级的交换区域。例如,如果你有一个较快的磁盘 (/dev/sda
) 和一个较慢的磁盘 (/dev/sdb
),给较快的设备分配一个更高的优先级。优先级可以在 fstab 中通过 pri
参数指定:
/dev/sda1 none swap defaults,pri=100 0 0 /dev/sdb2 none swap defaults,pri=10 0 0
或者通过 swapon 的 --priority
参数:
# swapon --priority 100 /dev/sda1
如果两个或更多的区域有同样的优先级,并且它们都是可用的最高优先级,页面会按照循环的方式在它们之间分配。
分片[编辑 | 编辑源代码]
不需要使用 RAID 提高交换的性能,只要在 /etc/fstab
中给交换设备设置相同的优先级,内核会将交换分片到多个设备。详情请参考 Software-RAID 指南。