为什么大多数人建议将swappiness值减少到10-20?

我在几个网站上看到建议将swappiness降至10-20以获得更好的性能。

这是一个神话还是不是?这是一个普遍规则吗? 我有一台配置为4GB内存和128GB固态硬盘的笔记本电脑,你建议我的swappiness值是多少?

谢谢。


8你列出的那些网站没有解释为什么他们推荐更改默认设置。这里的答案对于这个棘手的选择和复杂的问题来说要好得多。 - nealmcb
7个回答

因为大多数人认为交换=不好,如果您不减少交换性,系统将在实际上不需要时进行交换。这两者都不是真的。人们将交换与系统变得拥挤的时候联系在一起 - 然而,它主要是因为系统变得拥挤才进行交换,而不是相反。当系统进行交换时,它已经考虑到了性能成本,并决定不这样做会对系统性能或稳定性造成更大的整体损失。
总体而言,默认设置可以获得良好的性能和稳定性。我建议保持默认设置。Linux还有进一步改进内存管理以解决一些边缘情况的方法,但总体而言,交换性控制并不是一个好的解决办法 - 将其调整到一个方向可能修复一个问题,却会引发其他问题。如果可能的话,只需安装更多物理内存(并保持交换性不变)就能解决所有其他问题。
Linux如何使用RAM
任何未被应用程序使用的RAM都可以用作“缓存”。缓存对于快速、流畅运行的系统非常重要,可以加快对磁盘的读写速度。
如果您的应用程序增加了内存使用量,以至于几乎使用了所有的RAM,那么缓存将会减少,平均磁盘操作也会因此变慢。现在仅仅拥有几十兆字节或更少的缓存已经不够了。
如果应用程序进一步增加了内存使用量 - 假设您没有交换空间 - 您不仅没有空间来存储缓存,而且最终会耗尽内存,系统将不得不终止正在运行的进程。终止进程比减速更糟糕,因为它会导致系统不稳定、不可预测。
为了解决这两个问题,您的系统可以将一些很少使用的应用程序内存重新分配到磁盘上的交换空间中,从而释放RAM。额外的RAM可以防止进程因内存不足而死亡,并可以回收一些缓存,使磁盘操作更加顺畅。
这种重新分配并不是根据一个明确的截止点来进行的。在Linux开始交换之前,你并不会达到一定比例的分配。它采用了一种"模糊"算法。它考虑了很多因素,最好描述为"内存分配的压力有多大"。如果有很多"压力"来分配新的内存,那么它会增加一些被交换的机会以腾出更多空间。如果"压力"较小,则会减少这些机会。
您的系统有一个"swappiness"设置,可以帮助您调整如何计算这种"压力"。它经常被错误地表示为"RAM的百分比",但实际上它只是作为公式的一部分使用的值。建议的合理值在40到60之间,现在默认值是60。
让系统在需要时进行交换总体上是一件非常好的事情,即使您有很多RAM。如果系统需要时进行交换,可以让您放心,即使在临时低内存情况下(运行使用大量内存的短期进程时),您的系统也有第二次机会保持一切正常运行。如果您完全禁用交换,那么由于无法分配内存,您的进程可能会被终止。 当系统负载过重并且频繁进行交换时会发生什么? 交换是一个缓慢且代价高昂的操作,因此系统会避免使用它,除非计算结果显示在整体上通过牺牲缓存性能来弥补其不足,或者为了避免终止进程而必要。
很多时候,人们会看着他们的系统大量占用磁盘和交换空间,并将其归咎于交换。这是错误的方法。如果交换达到这种极端情况,说明交换是系统应对低内存问题的一种尝试,而不是问题的根本原因,没有交换,你的运行进程只会随机中断。 那桌面系统呢?它们需要采取不同的方法吗? 桌面系统的用户确实希望系统对用户发起的操作(如打开应用程序)有“即时响应”,这种操作有时会触发由于内存增加而引起的交换。
有些人尝试调整swappiness参数以增加系统对应用程序占用内存并且缓存空间不足的容忍度,以此来优化系统的反应速度。
然而,这只是在改变目标。第一个应用程序现在可能不需要进行交换操作就能加载,但它会为下一个加载的应用程序留下更少的空闲空间。同样的交换操作可能只会在你下次打开应用程序时发生。与此同时,由于缓存大小减小,系统性能总体上较低。因此,减少swappiness设置的任何好处可能很难衡量,有时可以减少交换延迟,但有时会导致其他性能下降。如果你知道自己在做什么,适当地减少swappiness可能是合理的,但将其降低到10以下可能会使系统对非常低的缓存大小具有容忍性,并且更容易在短时间内进行交换。
完全禁用交换应该避免,因为这样会失去对内存不足条件的额外保护,这可能导致进程崩溃或被终止。
迄今为止,最有效的解决方法是如果你负担得起的话,安装更多的RAM。
在已经有大量RAM的系统上是否可以禁用交换?
如果您的RAM比应用程序需要的要多得多,那么您很少需要交换空间。因此,在通常情况下禁用交换空间可能不会有任何影响。但是,如果您有足够的RAM,并且保持交换空间的启用状态也不会有任何惩罚,因为系统在不需要交换时不会进行交换。
唯一可能产生影响的情况是在系统内存不足并且缓存系统受到影响的情况下,这种情况下您可能需要交换空间。因此,当您有足够的内存时,可以放心地保持交换空间的正常设置,它永远不会对性能产生负面影响。
但是,交换空间如何加快系统速度?交换操作将数据从RAM转移到交换空间是一个缓慢的过程,但只有当内核非常确定通过保持合理的缓存大小所带来的整体益处大于此时才会进行。如果您的系统因磁盘读写过多而变得非常缓慢,那么交换空间并不是引起问题,而只是试图缓解问题。
一旦数据进入交换空间,它何时再次出来?
任何给定的内存部分只要被使用(读取或写入)就会从交换空间中返回。然而,通常被交换的内存是长时间未被访问且不会很快需要的内存。
将数据从交换空间转移出来与将其放入其中一样耗时。如果内核不需要,它就不会从交换空间中删除数据。当数据在交换空间中且未被使用时,它会为其他正在使用的内容和系统缓存腾出更多内存。
有哪些情况下降低交换性能是合适的呢?
是的。如果您运行的是专用于某个特定服务器应用程序的服务器,并且该应用程序不受系统缓存的影响。一些数据库服务器,如Oracle服务器、MySQL/MariaDB,在某些情况下建议将交换性能降低到1至10,因为这些数据库引擎使用自己的缓存。
请注意,这仅适用于您的系统专门用于执行该任务的情况,对于MySQL/MariaDB而言,仅当您使用纯粹的InnoDB或XtraDB而非MyISAM或Aria等引擎时才成立。如果您的系统的专用目的围绕着一个具有自己缓存且不受系统缓存影响的应用程序,降低交换性能可能是一个好主意。

2非常感谢您详细的描述。根据我的情况(4GB内存和128GB固态硬盘)以及我的使用方式(Java EE开发和在虚拟机中运行多个操作系统),我认为将swappiness值设置为20是合适的。您觉得呢? - Saeed Zarinfam
1我认为默认值60是最好的选择,这只是我的个人意见。 - thomasrutter
如果我没记错,默认的Ubuntu是60,在8 GB内存的情况下,有时Ubuntu会占用一点内存,当设置为10或更低时,Ubuntu不会占用任何内存。http://namhuy.net/1563/how-to-tweak-and-optimize-ssd-for-ubuntu-linux-mint.html - Blanca Higgins
4@BlancaHiggins,你有没有读过你评论的那篇帖子?你的评论似乎并没有准确描述swappiness的作用。 - thomasrutter
3这是一个非常出色的回答。非常感谢你对如此精彩的解释。 - Dan Barron
还有,请看一下这个链接:https://help.ubuntu.com/community/SwapFaq#What_is_swappiness_and_how_do_I_change_it.3F - azerafati
2虽然看起来可能不像,但是由于一些对“长篇大论”的指责,我已经努力将这个答案简化很多,同时仍保留相关信息。 - thomasrutter
1很高兴在这里看到这个答案...最近我看到很多人声称添加交换文件会降低性能。 - Rondo
6我认为那个SwapFaq中的一部分信息是误导性的:将其设置为100会“积极地”进行交换。我认为更准确的说法是,这是一个非常谨慎、主动的设置,在可用内存或缓存出现即使只有一点点不足的迹象时就开始进行交换。而像10这样的低设置更具有风险和刺激性,只有在可用内存非常低且缓存几乎完全消失的情况下才避免进行任何交换,这样会让系统没有太多的余地。 - thomasrutter
2官方文档并没有明确说明这一点,但我认为100不是swappiness的最大值,也不像许多人所说的那样是一个“百分比”。虽然我没有尝试过,但超过100的值可能会导致更早的交换。不过我并不推荐这样做。 - thomasrutter
这个回答似乎与我的实际经验相矛盾。当一个失控的进程导致我的笔记本电脑写入几个千兆字节到交换空间时,浏览器需要超过几天的时间才能恢复正常速度。当最终完成后,运行swapoff -a; swapon -a立即恢复了浏览器的速度。你能解释一下这种现象吗?你声称所需的内存会迅速恢复的说法似乎是错误的。 - David Roundy
@DavidRoundly不可能从交换空间中读取或写入内存。必须将其交换回来才能使用。尽管如此,这仅在每个页面的基础上发生,所以你所经历的可能是在接下来的几天里,你正在访问不同的已交换页面集并逐个释放它们。在这种情况下,swapoff会一次性完成所有这些操作,可能需要一些时间,但你会恢复到在内存耗尽之前的感觉。交换空间不是原因。当你完全耗尽内存时,无法调整交换空间以避免惩罚。 - thomasrutter
...但在您的特定情况下,swapoff可以通过一次性强制全部交换出来,而不是随机分散地逐个交换,从而防止后续的卡顿问题。 - thomasrutter

在一般的桌面电脑上,你通常会有4-5个活动任务占用50-60%的内存。如果将swappiness设置为60,那么大约1/4-1/3的活动任务页面将被交换出去。这意味着,对于每个任务的更改,对于每个新打开的标签页,对于每个JS执行,都会进行一次交换过程。
解决方案是将swappiness设置为10。通过实际观察,这会导致系统放弃磁盘IO缓存(在桌面上几乎不起作用,因为读/写缓存几乎不被使用。除非你不断地复制大文件),而不是将任何东西推入交换空间。 实际上,这意味着系统将拒绝交换页面,而是削减IO缓存,除非内存使用量达到90%。这反过来意味着流畅、无交换、快速的桌面体验。
然而,在文件服务器上,我会将swappiness设置为60甚至更高,因为服务器没有必须整体保留在内存中的巨大活动前台任务,而是有很多较小的进程,它们要么工作,要么休眠,并且不会立即改变状态。相反,服务器经常向客户端提供(原谅)完全相同的数据,使得磁盘IO缓存更有价值。因此,在服务器上,最好将休眠进程交换出去,为磁盘缓存请求释放内存空间。
在桌面上,然而,这个确切的设置会导致交换出实际应用程序的内存块,这些应用程序几乎不断地修改或访问这些数据。
奇怪的是,浏览器经常保留大块的内存,并且不断地修改它们。当这些块被交换出去时,如果需要重新请求它们,就需要一段时间 - 同时,浏览器会继续更新其缓存。这会导致巨大的延迟。实际上,你可能要等待2分钟才能加载一个新标签页中的单个网页。
桌面并不真正关心磁盘IO,因为桌面很少读写可缓存的重复大数据块。为了尽量减少交换,减少磁盘IO更有利于桌面,而不是将30%的内存保留给磁盘缓存,同时将30%的RAM(其中包含属于活跃使用的应用程序的块)交换出去。
只需启动htop,打开浏览器、GIMP和LibreOffice - 在那里加载一些文档,然后浏览几个小时。真的很简单。

5+1 用于服务器与台式机差异描述。服务器的磁盘缓存可以在磁盘领域上完成。 - Dee
1如果是这样的话,为什么Ubuntu的服务器版和桌面版都默认使用60的swappiness值呢?如果你所说的是真的,那么桌面版默认值应该是20甚至10才更合理,但事实并非如此。 - JAB
1对于swappiness是指直接将百分比的内存交换出去的说法有什么依据?我不认为它是这样工作的。 - Xen2050
4它不是的。Swappiness与RAM的百分比无关。它是一个旋钮,用于调整模糊算法在特定问题情况下更或者更少地进行交换。我还认为这个回答中关于服务器和桌面工作负载的描述做了一些并不总是成立的假设。 - thomasrutter
6这个回答不清楚,充斥着错误的假设和断言。目前被接受的答案更准确,我要警告任何人不要轻信这个回答中的任何内容。 - agittins
+1 对于这个双关语:服务器“服务”数据。 ;) - loved.by.Jesus
Swappiness与这个回答声称的“RAM百分比”完全无关。这个回答的整个前提都是错误的,甚至在涉及像缓存对桌面性能无关紧要这样的严重不准确之前。 - thomasrutter

如果您在Linux系统上运行Java服务器,您应该考虑将swappiness从默认值60大幅降低。因此,20确实是一个很好的起点。对于垃圾回收过程来说,交换是一个杀手,因为每次收集都需要触及进程内存的大部分。操作系统无法检测到这些进程并为它们做正确的处理。在生产应用服务器中,最佳实践是尽可能避免交换。

1如果你将服务器专门用于某种工作负载,而且你知道这种负载不会从系统缓存中受益(比如数据库服务器),那么减少交换空间可能是有意义的。但我认为垃圾回收并不是一个足够特殊的情况。如果内存经常被访问,它就不会被交换出去,而是会保留在物理内存中。唯一的例外是在严重的低内存情况下,此时交换并不起作用。 - thomasrutter
1通常,所有的JAVA垃圾收集器都是分代的 - 有年轻代(堆的1/3)经常被收集和分配池频繁使用,而老年代(堆的2/3)相对较少被GC触及,因此似乎可以无问题地交换老年代页面。 - ALZ

我建议在打开系统监视器的同时进行一些实验,以了解您的机器承受了多大的负载。我也使用4GB内存和128GB固态硬盘,所以将swappiness值更改为10,不仅在负载下提高了性能,而且还会延长固态硬盘的寿命,因为它会减少写入次数。
要了解如何进行这个操作并获得完整的解释,请参考下面的YouTube视频教程。

http://youtu.be/i6WihsFKJ7Q


1你做的视频很棒,但是视频并没有直接回答问题,更像是一个关于如何改变swappiness的教程。 - jmunsch
1+1 对于 SSD 寿命的提示,最好如果系统尽可能是只读的,其余部分应该保留在内存中,而今天,在当前桌面电脑上,内存通常不是一个大问题。 - Dee

我想从一个大数据性能工程师的角度来补充一些关于2017年技术背景的观点。
根据我的个人经验,通常我会禁用交换空间以确保系统以最大速度运行,但在我的工作站上遇到特定问题时,我发现将swappiness设置为1和10会导致系统冻结(永久)和长时间暂停。对于这个特定应用程序,将swappiness设置为80比默认值60能够提供更好的性能和更短的暂停时间。请注意,我有8GB的RAM和4个256GB的交换空间,支持的是1个HDD。通常我会列出我在基准测试中看到的精确统计数据和完整的硬件规格,但我还没有进行任何测试,并且这是一台最近购买的低端台式机,在这里并不重要。
在我之前的公司,我们没有在Spark服务器上启用swappiness的原因是,当我们发现性能不佳时,我们将其视为重新设计数据流水线和数据结构以更高效方式运行的信号。我们也不想对HDDs/SSDs进行基准测试。此外,交换如此多的RAM需要每个节点10-30个磁盘进行并行写入,以最小化磁盘访问时间。
今天,20年前和20年后,情况仍然是一些问题对于RAM来说太大了。有了无限的时间和金钱,我们可以购买/租赁更多的硬件或重新设计任何过程,以达到理想的性能水平。交换只是一个让我们忽略真正问题的hack(我们没有足够的内存,也不想花更多的钱)。
对于那些认为更高的交换率是个坏建议的人,这里有一点观点。过去,硬盘只有几KB的缓存,如果有的话。接口是IDE/Parallel ATA。CPU总线以及RAM和其他许多东西也都慢得多。简而言之,系统在各个方面都非常慢(相对于今天)。几年前,硬盘使用SATA3。今天,它们使用具有显著延迟改进的NVMe协议。硬盘有很多MB的缓存。最有趣的部分是当您使用现代SSD(具有更稳定的读写耐久性和性能)作为交换存储,并且使用NVMe或PCIe时。这是成本和性能之间的最佳折衷。请不要尝试使用廉价或旧的SSD进行此操作。
Swap+SSD!使用高性能的易失性存储器,我强烈建议尝试使用较高的交换空间值。这主要取决于内存访问模式(随机访问所有内存还是很少访问大部分内存)、内存使用情况、磁盘带宽是否已经饱和以及抖动的实际成本。

一个个人的轶事。我之前不知道这个swappiness,回想起来它可能解决了我的问题。我的系统很旧,内存只有4GB。
我将Linux操作系统升级到了下一个最新的长期支持版本。那个版本“被动地”使用了更多的内存。这导致我的系统使用了更多的交换空间。由于交换空间在硬盘上,系统开始变得缓慢。
查看统计数据后发现,RAM和交换空间的总和并没有超过我的最大RAM容量。问题部分是因为'Linux专家'提到浏览器经常保留大块内存,并且不断修改。所以我使用的是Firefox(尤其是YouTube很占资源),因此大块内存被放入交换空间,但实际上是需要的。
最终我增加了更多的RAM,这确实解决了我的问题,但如果我尝试将swappiness设置为较低的值,也许可以推迟购买RAM的时间。我不后悔购买RAM,这是一个很好的升级,但并非每个人都能进行升级。

可能是因为Linux在启动或打开程序时需要从磁盘读取配置文件等,所以才会出现许多被认为是交换行为的情况。因此,在假设硬盘访问是由于交换而引起之前,最好使用系统监视器程序进行查看。