如何配置swappiness?

我需要一种逐步、简单且易于配置swappiness的方法。

25一行代码 sudo bash -c "echo 'vm.swappiness = 15' >> /etc/sysctl.conf" - redanimalwar
17@redanimalwar 你还需要运行 sudo sysctl -p 命令来加载 sysctl.conf 文件中的新 swappiness 值,否则更改只会在下次重启时生效。 - waldyrious
3个回答

Linux内核提供了一个可调整的设置,用于控制交换文件的使用频率,称为swappiness。

swappiness设置为意味着除非绝对必要(即内存不足),否则将避免使用磁盘,而swappiness设置为100意味着程序将几乎立即被交换到磁盘上。

Ubuntu系统默认设置为60,这意味着如果内存使用量接近我的RAM一半,交换文件将经常被使用。您可以通过运行以下命令来检查您自己系统的swappiness值:

one@onezero:~$ cat /proc/sys/vm/swappiness
60

由于我有4 GB 的 RAM,我想将其调整为10或15。当我的 RAM 使用率达到80% 或90% 时,交换文件才会被使用。要更改系统的 swappiness 值,请以 root 身份打开 /etc/sysctl.conf 文件。然后,在文件中更改或添加以下行:
vm.swappiness = 10

应用更改。

sudo sysctl -p

您还可以在系统运行时更改值,方法如下:

您可以在系统运行时更改值:

sysctl vm.swappiness=10

你也可以通过以root身份运行swapoff -a,然后再运行swapon -a来清除你的交换空间,而不必重新启动系统以达到相同的效果。
计算你的交换空间公式如下:
free -m (total) / 100 = A

A * 10

root@onezero:/home/one# free -m
             total       used       free     shared    buffers     cached
Mem:          3950       2262       1687          0        407        952
-/+ buffers/cache:        903       3047
Swap:         1953          0       1953

所以总共是3950 / 100 = 39.5 * 10 = 395。
这意味着当剩下10 %(395 MB)的内存时,系统将开始使用交换空间。

什么是swappiness?

swappiness参数控制内核将进程从物理内存移出并移到交换磁盘的倾向。由于磁盘比RAM慢得多,如果进程过于积极地被移出内存,这可能导致系统和应用程序的响应时间变慢。

  • swappiness的值可以在0到100之间。
  • swappiness=0:
    • 内核版本3.5及更高:禁用swapiness。
    • 早于3.5的内核版本:尽可能避免将进程从物理内存中交换出去。
  • swappiness=1:
    • 内核版本3.5及以上:最小化swapiness而不完全禁用它。
  • swappiness=100:
    • 告诉内核积极地将进程从物理内存中交换出去并移到交换缓存中。

参见http://en.wikipedia.org/wiki/Swappiness

Ubuntu的默认设置是swappiness=60。减小swappiness的默认值可能会提高典型的Ubuntu桌面安装的整体性能。建议使用swappiness=10,但也可以自由尝试其他值。

示例

开始使用交换空间时达到91%

输入图像描述 因为我已经配置了我的系统和虚拟机以利用90%的内存,所以在90%时没有发生交换。

之后我打开了一些应用程序,如Firefox和Shutter,由于内存使用量超过90%,开始进行交换。


156Swappiness为100并不意味着程序会立即被交换出去,而60或90的值也不表示当内存使用达到60%或90%时就会使用交换空间。它是一个偏好比例,用于决定是从缓存中窃取页面还是将其交换出来以释放一些内存,当内存不足时起作用。较低的值会更倾向于从缓存中窃取页面,而较高的值则更倾向于尝试将页面交换出去。这个设置只有在内存几乎全部被使用,并且内核需要选择如何释放一些内存时才会产生任何影响。 - psusi
79你需要指出,未被运行程序占用的内存被用作磁盘缓存...因此,通过降低交换性(swappiness),你增加了程序不被交换出去的机会,但同时也减小了磁盘缓存的大小,可能导致磁盘访问变慢。所以这个设置对实际性能的影响并不那么直接...当然,欢迎你进行实验,但我怀疑默认设置是由对这个主题有足够了解的人设定的 :) - Sergey
22@Sergey,讽刺的是,那些内存较小的人往往会尝试各种技巧来提升性能,并且对于他们来说,60甚至更高的数字可能是最佳选择。而我们这些拥有大量内存的人将其设置为10,虽然并没有获得太多好处,但如果他们这样做的话,他们将失去更多。 - Jon Hanna
1是的,我在一台只有1/2Gb内存的旧电脑上完成了这个操作,但是我一直无法弄清楚是什么导致硬盘不停地运转而使电脑变得非常慢。通过使用iotop,我发现电脑一直在搜索不存在的交换空间。现在我将它重新设置为60,硬盘活动明显减少,gnome-shell也能够正常运行而不会变得卡顿。 - mchid
@Sergey,你有关于未使用的RAM被用作磁盘缓存的来源/参考资料吗? - Freedom_Ben
10@Freedom_Ben: 看看 http://www.linuxatemyram.com :) - Sergey
1只需使用 sysctl vm.swappiness 命令,您就可以读取实际值。 - rubo77
如果你的文件系统缓存由具有自己进程的ZFS管理,会怎么样? - CMCDragonkai
3这个解释大体上是正确的,但是建议改变默认的swappiness是适得其反的。让计算机减少交换通常会导致更多的I/O,因为它会不断重新加载无法保留在缓存中的有用数据。 - Gilles 'SO- stop being evil'
如何判断自己的swapiness版本是多少?大于等于3.5。 - Elijah Lynn
啊,这是内核版本3.5+,原始来源在这里:https://www.percona.com/blog/2014/04/28/oom-relation-vm-swappiness0-new-kernel/ - Elijah Lynn
5我的经验是,与在8GB内存的Ubuntu 14.04上设置为swappiness 60相比,将swappiness设置为10时,我得到了更好的响应时间。Eclipse不再像以前那样经常冻结。Unity不再频繁冻结和完全锁定(之前每天都会发生)。我的硬盘工作量大大减少,当使用超过4GB的内存时,设置为swappiness 60时,硬盘操作一直持续。但是,作为一个Java开发人员,我认为默认设置并不适合我这个目标群体。在我的Ubuntu设置中,没有任何设置是默认的。在更改您的设置时要小心。 - mondjunge
9这里只是留下一个类似的讨论 - http://unix.stackexchange.com/questions/88693/why-is-swappiness-set-to-60-by-default - Elijah Lynn
1值得注意的是,存储交换文件的媒体类型以及交换设备所承载的其他流量量,对性能有着巨大的影响。如果您的交换文件存储在与正在运行的操作系统一起使用的旋转介质(硬盘驱动器)上,那么您可能希望尽量减少交换操作。另一方面,如果交换文件存储在固态硬盘(无论是否与正在运行的操作系统一起使用),庞大的IOPS数量和零搜索时间的组合意味着交换操作的响应速度更快,因此使用更多交换操作相对无害。虽然不及内存快速,但远不及旋转介质糟糕。 - killermist
1@killermist 但至少传统观点认为,交换对SSD的寿命不利;通常教程会建议将交换性设置为1以适用于任何SSD。你知道这是否属实吗?(传统观点总是说很多事情……) - Luke Maurer
1@LukeMaurer 这里有另一个关于是否在SSD上最小化swappiness的答案 http://askubuntu.com/questions/652337/why-no-swap-partitions-on-ssd-drives/652342#652342?newreg=130e31746d05473aa90b51e2b289a065 #TLDR 对早期的SSD来说可能适用,但对于现代的SSD来说应该是不必要的。 - jerclarke
1不妨将对系统文件"/etc/sysctl.conf"的修改,改为写入某个"/usr/local/lib/sysctl.d/*.conf"文件中,这样或许更好。 - adf88
@Sergey vw.swappiness=0并不一定意味着减少磁盘缓存(例如,在有大量空闲内存的情况下,它并不会减少)。 - Geremia
@Geremia:如果你有很多空闲的RAM(程序和磁盘缓存都没在使用),那么即使swappiness值很高,程序也不会被交换出去。只有当内核认为有更好的用途来利用那些当前不需要的代码/数据所占用的RAM时,它们才会被交换出去。我这台机器上有32GB的RAM,尽管打开了很多程序,但交换分区仍然没有被使用(swappiness=60)。 - Sergey
4由于我有4 GB 的内存,所以我想将其降低到10或15。在2018年,其中一半用于在Ubuntu上运行Slack。 - d4nyll
1正如@Sergey所指出的那样,你的“空闲”内存实际上并没有浪费,而是用于磁盘缓存。这意味着在某些情况下,有一定比例的交换内存和空闲内存(用于磁盘缓存)之间的平衡是完全可以接受的。除非你的系统中有非常多的内存,并且你认为所有的空闲内存都没有被用作磁盘缓存。因此,“free -m”列中的实际空闲内存可能接近零,这是可以接受的。 - Melroy van den Berg
2正如其他人已经指出的那样,这个答案是错误的。它不应该被标记为采纳的答案。Swappiness 控制着交换文件支持的页面与匿名内存之间的比例。关于交换特别是在快速 I/O 设备(如 SSD 或甚至 ZRAM)上的更深入的技术讨论,可以参考这个补丁系列和相关讨论:https://lore.kernel.org/patchwork/patch/685711/ - user228505
4对于一台配备 8GB RAM 和快速 SSD 的笔记本电脑来说,将 swappiness 设置为 10 使得 Ubuntu 18.04 运行得非常流畅,类似于 @mondjunge 的体验。不再出现 GNOME 卡顿,也不再有当操作系统交换文件出现故障时鼠标光标跳跃的情况。我经常同时运行的资源消耗最高的应用程序是拥有 50+ 个标签的 Chrome 浏览器和 WebStorm IDE(一个 Java 应用程序)。 - Dan Dascalescu
所以,swapiness 60 的意思是当我的 RAM 使用率达到 40% 时开始使用 swap? - userDepth
1@userDepth 不行,你可以在这里查看(https://askubuntu.com/questions/103915/how-do-i-configure-swappiness#comment120186_103916)。请在添加评论之前仔细阅读评论,尤其是那些高赞的评论! - DJCrashdummy
在这里阅读最新的Linux内核源代码文档中有关swappiness的说明:链接。现在最大值是200而不是100,0表示“当空闲和文件支持的页面数量低于区域内的高水位标记时,内核将不会启动交换”——不管那意味着什么。 - Gabriel Staples
1这个答案在多个方面都是错误的。请参考这些评论中发布的其他解释之外的一种不太技术性的解释:https://www.howtogeek.com/449691/what-is-swapiness-on-linux-and-how-to-change-it/ - authentictech

我需要一种逐步简单且易于操作的方法来配置swappiness。
我想在这里进一步阐述已有答案的内容,加上以下信息:
1. 如何更改swappiness的简明总结。 2. 引用最新的Linux内核源代码(如果感兴趣,请点击此处下载)中关于"swappiness"的真正含义以及其范围的引述。
下面是具体步骤:
# read current swappiness setting
sysctl vm.swappiness
# or (same thing)
cat /proc/sys/vm/swappiness

# change setting to zero
sudo sysctl vm.swappiness=0

上述命令在重新启动后不会保留。要使设置持久化,您需要使用sudo并编辑位于/etc/sysctl.conf的文件,在其末尾添加所需的swappiness设置。示例:
# edit the file with the `nano` editor
sudo nano /etc/sysctl.conf

将以下内容添加到"/etc/sysctl.conf"的末尾:
# my custom swappiness setting
vm.swappiness=0

如果您选择仅编辑该文件以设置自定义的swappiness设置,而不是使用sudo sysctl vm.swappiness=0进行设置,则要激活在文件中设置的新设置,您需要重新启动或调用以下命令重新加载配置文件:
# reload just the "/etc/sysctl.conf" config file
sudo sysctl --load

# or: from `man sysctl`:
#
#       Load settings from all system configuration files.
#       /run/sysctl.d/*.conf
#       /etc/sysctl.d/*.conf
#       /usr/local/lib/sysctl.d/*.conf
#       /usr/lib/sysctl.d/*.conf
#       /lib/sysctl.d/*.conf
#       /etc/sysctl.conf
sudo sysctl --system

在运行上述任一命令的末尾,终端将打印以下内容到标准输出:
``` vm.swappiness = 0 ```
要查看你当前在 `/etc/sysctl.conf` 中的设置,请执行以下操作:
cat /etc/sysctl.conf

2. 从Linux内核开发者的嘴里说出来,swappiness是什么

按照我在这里的指示下载Linux源代码:获取官方Linux内核源代码的位置和方法

如Linux稳定库中的git blame Documentation/admin-guide/sysctl/vm.rst所示,此文档由Peter W Morreale、Mauro Carvalho Chehab和Johannes Weiner编写(请参见此处的内核源代码)(已加重点,并稍作格式修改):

swappiness

==========

这个控制用于定义交换和文件系统页面的相对IO成本,取值范围在0到200之间。在100时,VM假定IO成本相等,因此会对页面缓存和支持交换的页面施加内存压力;较低的值表示更昂贵的交换IO,较高的值表示更便宜的IO。

请记住,在内存压力下,文件系统IO模式往往比交换的随机IO更有效率。最优值需要进行实验并且还与工作负载相关。

默认值为60。

对于内存中的交换,例如zram或zswap,以及具有比文件系统更快设备上的交换的混合设置来说,可以考虑超过100的值。例如,如果与交换设备的随机IO平均快于从文件系统读写,则应该将swappiness设置为133(x + 2x = 200,2x = 133.33)。

在0时,内核将不会启动交换,直到一个区域中的可用和文件支持页面的数量少于高标记。

所以,值不再在0到100之间变动。从2020年6月3日的此提交哈希c843966c556d7开始,该值现在范围从0到200。 在此之前的提交哈希497a6c1b09902b22ceccc0f25ba4dd623e1ddb7d中提到了这一点。

swappiness

==========

这个控制参数用于定义内核交换内存页面的侵略程度。较高的值会增加侵略性,较低的值会减少交换量。当一个区域中的空闲和文件支持的页面数量低于高水位标记时,值为0的情况下,内核不会启动交换。

默认值为60。

至少从Linux内核版本v2.6.12-rc2(2005年)开始,通过git blamemm/vmscan.c文件中设置的方式显示,默认的swappiness值一直是60。

我应该使用哪个swappiness值?

我强烈推荐使用vm.swappiness=0!这样我的机器运行起来好太多了。根据我的经验在这里的回答中
我发现将swappiness设置为0可以显著提高我的系统性能。我的系统配备了32GB的RAM,64GB的交换文件,并且使用高速的m.2 SSD。然而,由于持续不断地内存不足,我经常遇到1到2分钟的卡顿期,此时kswapd0正在运行(通过top显示),尝试为一些内存占用较高的应用程序(如Chrome、Slack、Eclipse或Google Meet)进行内存交换。当RAM使用率达到80%时,这些卡顿就开始出现。在此期间,电脑将变得完全无法使用,甚至无法在终端中输入命令或点击菜单。
将swappiness设置为0 有很大帮助!直到RAM使用率达到90%时,我才开始出现非常高的CPU使用率。交换空间仍然会被充分利用,但更加高效。当我的RAM几乎满了时,电脑会变得非常缓慢,但仍然勉强可用,而不是完全无法使用!
在这里可以看到一些我遇到的症状,最初我以为是Google Meet的一个错误,但现在我认为是内存交换导致了电脑变慢:https://github.com/ElectricRCAircraftGuy/bug_reports/issues/3#issue-1177137900

在我的系统上:

  • vm.swappiness=60时,当内存使用率达到约79%时,我会看到持续1到2分钟的100% CPU卡顿,每4到6分钟出现一次,持续不断。这在使用Google Meet时尤为严重和突出。
  • vm.swappiness=0时,就不会发生这种情况。在内存使用率达到80%时,我仍然可以正常运行,但在90%的内存使用率下会开始出现明显的迟缓,但不会像之前那样完全卡死。
    • 即使将swappiness设置为0,我也会在RAM使用量达到0到3%时看到一些交换空间的使用(几MB),并且在80%到90%的RAM使用量时会有大量的交换空间使用。

参考资料:

  1. https://linuxize.com/post/how-to-change-the-swappiness-value-in-linux/ - 我在这里学到了上面大部分的sysctl命令
  2. https://www.cyberciti.biz/faq/reload-sysctl-conf-on-linux-using-sysctl/ - 我在这里学到了上述sysctl --system命令

相关:

  1. kswapd0正在占用大量的CPU - 有用,但这个引用完全是错误的:

    其中0表示在剩余100%中应该使用SWAP的百分比(当你的RAM剩余0%时,SWAP将开始接收数据)。

  2. 我的答案- 我需要这个swappiness信息给他们:

    1. *****非常有用- 我经常参考这个:问题:Eclipse和Eclipse索引器占用了我所有的资源/CPU%
    2. Unix & Linux:将swappiness设置为0与swapoff之间有什么不同

对于没有任何实际交换分区/文件的ZRAM交换,使用100。它会预先压缩所有可以预先压缩的内容,保持缓存完整,并在需要时快速解压数据(此外,如果没有真正的交换,您需要将admin_reserve_kbytes增加到原来的两倍甚至四倍,以避免整个系统在低内存下冻结而不是关闭一个占用大量内存的应用程序)。
对于具有实际交换分区的SSD,请使用1。它会尽可能地防止交换,牺牲缓存(但缓存可以轻松从SSD中重新读取)。