当内存压力上升时,Linux 必须在回收缓存的文件页和将不活跃的匿名页移动到已配置的交换区之间做出选择。该交换区可以是磁盘支持的分区、交换文件,或者是压缩内存设备(如 zram)。

Swappiness 是影响这一选择的 Linux 内核设置,它通过为交换 I/O 和文件系统分页分配相对成本来发挥作用。较低的值将交换视为更昂贵,而较高的值则将其视为更便宜。

本文解释了如何在 Linux 中检查和更改 swappiness 值,包括使用 sysctl 临时更改以及使用持久化的 sysctl 配置永久更改。

快速参考

任务命令
检查当前 swappinesscat /proc/sys/vm/swappiness
通过 sysctl 检查sysctl vm.swappiness
临时设置 swappinesssudo sysctl vm.swappiness=10
永久设置 swappiness将 vm.swappiness=10 添加到 /etc/sysctl.d/99-swappiness.conf
应用 sysctl 更改sudo sysctl --system
查看哪些交换设备处于活动状态sudo swapon --show

检查 Swappiness 值

要检查系统当前的 swappiness 值,请使用以下 cat 命令:

终端
cat /proc/sys/vm/swappiness

大多数 Linux 发行版上的默认 swappiness 值为 60:

输出
60

另一个可用于检查 swappiness 值的命令是 sysctl:

终端
sysctl vm.swappiness
输出
vm.swappiness = 60

更改 Swappiness 值

Swappiness 不是百分比,也不是开启或关闭交换的开关。内核将其视为交换 I/O 相对于文件系统 I/O 的相对成本。在 5.8 及更高版本的内核上,该值范围为 0 到 200,100 是平衡点,此时内核假设换出页面和重新读入文件页的成本相同。低于 100 的值告诉内核交换是更昂贵的选项,而高于 100 的值则告诉它交换比返回文件系统更便宜。

默认值 60 使内核倾向于在交换匿名内存之前丢弃文件支持的页面,当交换位于磁盘上时,这是一个合理的折衷方案。

在内核 5.8 之前,上限是 100。在较旧的内核上(例如 Ubuntu 20.04 中的 5.4 系列),写入更大的值会失败。如果不确定使用的是哪个内核,请运行 uname -r。

以下是该范围在实践中的表现:

  • 0 - 内核尽可能避免交换,只有当空闲页和文件支持的页面低于区域高水位线时才开始交换。
  • 10–30 - 轻度交换,推荐用于注重响应速度的桌面和工作站。
  • 60 - 默认值,适用于大多数通用系统。
  • 100 - 交换 I/O 和文件系统 I/O 被视为同等昂贵。
  • 133–180 - 交换被视为比文件系统分页更便宜,当 zram 或 zswap 比文件系统 I/O 更快时,这个范围值得测试。

访问磁盘上的交换比访问物理内存慢得多,因此较低的 swappiness 值通常能提高使用交换分区或交换文件的桌面系统的响应速度。

工作负载起始范围
使用磁盘交换的桌面/工作站10–15
通用服务器30–60
数据库服务器(MySQL、PostgreSQL)1–10
使用快速 NVMe 交换的系统20–40
使用 zram 或 zswap 的系统100–180

这些值是起点,而非固定建议。最优值取决于你的工作负载、可用内存和交换设备。请小幅度调整,并在每次更改后监控性能。

临时更改 Swappiness #

要在运行时设置 swappiness 值而无需重启,请以 root 身份或使用 sudo 运行 sysctl:

终端
sudo sysctl vm.swappiness=10

此更改立即生效,但重启后将丢失。

验证更改是否生效:

终端
sysctl vm.swappiness
输出
vm.swappiness = 10

永久更改 Swappiness #

要使更改在重启后持久生效,请创建专用的 sysctl 配置文件,而不是直接编辑主配置文件:

终端
sudo nano /etc/sysctl.d/99-swappiness.conf

添加以下行:

/etc/sysctl.d/99-swappiness.conftxt
vm.swappiness=10

保存文件并在不重启的情况下应用更改:

终端
sudo sysctl --system

你仍然可以使用 /etc/sysctl.conf,但 /etc/sysctl.d/ 中的专用文件更易于维护,且在升级期间不太可能被替换。

检查交换使用量

当系统处于内存压力下且有活动交换时,swappiness 才有意义,因此在更改前后查看当前状态是值得的。最快的方法是使用 free 命令:

终端
free -h
输出
               total        used        free      shared  buff/cache   available
Mem:            15Gi       6.2Gi       1.1Gi       412Mi       8.4Gi       8.5Gi
Swap:          4.0Gi       128Mi       3.9Gi

Swap 行显示有 4 GiB 交换空间,但仅使用了 128 MiB,因此内核几乎没有使用它。在这种状态下降低 swappiness 不会产生明显差异,因为仍有可用内存,内核没有回收内存的压力。

要查看哪些设备提供该交换空间,请运行 swapon:

终端
sudo swapon --show
输出
NAME      TYPE SIZE  USED PRIO
/swapfile file   4G  128M   -2

当有多个交换设备处于活动状态时,PRIO 列很重要,因为内核会优先填充优先级较高的设备。有关内存使用情况的更全面视图,请参阅我们关于在 Linux 中检查内存使用情况的指南。

使用 zram 的系统上的 Swappiness

降低 swappiness 的建议假设交换位于磁盘上,但这一假设并非在所有情况下都成立。Fedora 自 Fedora 33 起默认启用 zram 交换设备,Pop!_OS 在安装过程中也会配置一个。zram 是驻留在内存中的压缩块设备,因此向其交换的成本是压缩操作而非磁盘写入。

你可以从 swapon 输出中区分这两者。基于 zram 的系统如下所示:

输出
NAME       TYPE      SIZE USED PRIO
/dev/zram0 partition   4G   0B  100

因为从 zram 读回页面通常比从文件系统读回被逐出的页面更便宜,所以高于 100 的值可能是有意义的。值为 10 可能导致内核回收工作负载很快会再次需要的文件缓存,但结果取决于工作负载和存储。

内核文档给出了一个选择值的公式:如果交换 I/O 平均比文件系统 I/O 快两倍,则将 swappiness 设置为 133,即 200 点刻度的三分之二。要测试该值而不使其持久化,请运行:

终端
sudo sysctl vm.swappiness=133

此更改将持续到下次重启。运行你的常规工作负载,并在决定是否保留之前比较内存压力、交换活动和响应速度。

Pop!_OS 提供了一个特定于发行版的示例。其 zram 服务使用 zstd 压缩,仅在创建其 zram 设备后才应用 swappiness 值 180 和 vm.page-cluster=0。该服务在运行时应用这些值,而不是将它们存储在通用的 sysctl 配置中,因此如果禁用该服务,这些值不会保持活动状态。

vm.page-cluster 设置控制内核一次尝试从交换中读回多少页。它是一个对数值,因此 0 表示单个页面,默认值 3 表示八个页面。Pop!_OS 在使用 zstd 时使用 0,但不应仅根据存在 zram 设备就复制此值。

故障排除

更改在重启后未保留
sysctl vm.swappiness=N 命令仅为当前会话设置值。要使其永久生效,请将 vm.swappiness=N 添加到诸如 /etc/sysctl.d/99-swappiness.conf 的文件中,并运行 sudo sysctl --system。

运行 sysctl 时权限被拒绝
更改内核参数需要 root 权限。请在命令前加上 sudo,或先使用 sudo -i 切换到 root。

设置高于 100 的值失败
0 到 200 的范围在内核 5.8 中引入。在更早的版本上,最大值为 100,更大的值将被拒绝并显示 sysctl: setting key "vm.swappiness": Invalid argument。使用 uname -r 检查正在运行的内核,并在这些系统上保持在 100 或以下。

Swappiness 值没有明显效果
Swappiness 用于调整内存压力下回收文件映射页与交换匿名页之间的平衡。如果系统没有处于内存压力下,更改该值可能不会产生明显的差异。

更新或升级后值被重置
某些系统软件包会在升级期间替换 /etc/sysctl.conf。请改用专用的 drop-in 文件:创建 /etc/sysctl.d/99-swappiness.conf,并写入一行 vm.swappiness=10。Drop-in 文件在升级过程中会被保留。

常见问题

Linux 最佳的 swappiness 值是多少?
这取决于工作负载以及交换空间所在的位置。对于使用磁盘交换的桌面系统,10 到 15 是常见的起始范围。对于数据库服务器,建议从 1 到 10 之间开始,并监控内存压力。在使用 zram 交换的系统上,当交换 I/O 比文件系统分页更快时,值得测试高于 100 的值。默认值 60 对于一般服务器来说是一个合理的起点。

Swappiness 值可以大于 100 吗?
可以,在 5.8 及更新版本的内核上。该范围已扩展到 200,以便该设置能够描述交换比文件系统更快的系统,例如 zram 和 zswap。在较旧的内核上,100 仍然是最大值。

Swappiness 为 0 意味着什么?
值为 0 表示让内核尽可能避免交换,但并不会完全禁用交换。如果内存耗尽,内核仍会使用交换空间。要完全禁用交换,请运行 sudo swapoff -a。

如何在 Ubuntu 中查看 swappiness 值?
运行 cat /proc/sys/vm/swappiness 或 sysctl vm.swappiness。这两种方法在 Ubuntu、Debian、Fedora 以及其他 Linux 发行版上都可以使用。

在 Linux Mint 上应该使用什么 swappiness 值?
Linux Mint 使用基于磁盘的交换文件或交换分区,而不是 zram,因此适用桌面系统的建议:在 /etc/sysctl.d/99-swappiness.conf 中设置 vm.swappiness=10,然后运行 sudo sysctl --system。先运行 sudo swapon --show,确认没有 /dev/zram0 条目。

更改 swappiness 会提升性能吗?
在内存充足的系统上,降低 swappiness 可以减少不必要交换所造成的磁盘 I/O,从而提高响应速度。在内存非常少的系统上,交换不可避免,因此该值的影响较小。

更改 swappiness 后需要重启吗?
不需要,如果使用 sudo sysctl vm.swappiness=N,更改会立即生效。要同时使其在重启后仍然保留,请将 vm.swappiness=N 添加到 /etc/sysctl.d/99-swappiness.conf,然后运行 sudo sysctl --system。