如果我有足够多的 RAM,我是否需要交换空间?

IQA*_*eas 97 memory swap

据我了解,Linux 中交换分区的目的是从 RAM 中释放一些“不经常访问”的信息,并将其移动到硬盘驱动器上的特定分区(代价是读取或写入速度变慢)到),本质上允许主动应用程序更多的“高速内存”。

这非常适合当您使用的是 RAM 量较小的机器并且不想在用完时遇到问题时。但是,如果您的系统有16 GB32 GB的 RAM,并且假设您没有为 StackExchange 运行 MySQL 数据库或在 Linux 中编辑 1080p 全长电影,是否应该使用交换分区?

Dam*_*mon 105

是的。

您绝对应该始终启用交换,除非有非常令人信服的、令人生畏的原因(例如,根本没有磁盘,或者只有网络磁盘)。您是否应该按照经常推荐的荒谬大小(例如,两倍的 RAM)进行交换?嗯,没有

原因是交换不仅在您的应用程序消耗的内存多于物理 RAM 时才有用(实际上,在这种情况下,交换根本不是很有用,因为它会严重影响性能)。现在交换的主要动机不是神奇地将 16GiB 的 RAM 变成 32GiB,而是更有效地使用已安装的可用 RAM。

在现代计算机上,RAM 不会闲置。未使用的 RAM 是您也可以不购买并存钱的东西。因此,您加载的任何内容或以其他方式进行内存映射的任何内容,任何可能在以后任何时候(受安全约束限制)被任何人重用的内容都将被缓存。机器启动后不久,所有物理 RAM 都将用于某些用途。

每当您从操作系统请求新的内存页面时,内存管理器必须做出明智的决定:

  1. 从缓冲区缓存中清除页面
  2. 从映射中清除页面(在大多数系统上实际上与 #1 相同)
  3. 移动一个长时间未访问的页面——最好永远不要——交换(这实际上甚至可能主动发生,不一定在最后一刻)
  4. 杀死你的进程,或者杀死一个随机进程(OOM)
  5. 内核恐慌

选项 #4 和 #5非常不受欢迎,只有在操作系统绝对没有其他选择时才会发生。选项 #1 和 #2 意味着你扔掉了一些你可能很快就会再次需要的东西。这会对性能产生负面影响。

选项 #3 意味着您将(可能)很快不需要的东西移到慢速存储上。这很好,因为现在您确实需要的东西可以使用快速 RAM。

通过删除选项 #3,您有效地限制了操作系统执行 #1 或 #2。从磁盘重新加载页面与从交换区重新加载页面相同,除了通常不太可能从交换区重新加载(由于做出了正确的分页决策)。

换句话说,通过禁用交换,您将一无所获,但会限制操作系统在处理内存请求时有用的选项数量。这可能不是,但很可能劣势(永远不会是优势)。

[编辑]

在中细心的读者mmap 手册页,专门的描述MAP_NORESERVE,会发现另一个很好的理由,为什么互换是有些必要的,甚至与“足够”的物理内存的系统:

“当没有保留交换空间时,如果没有可用的物理内存,则在写入时可能会收到 SIGSEGV。”

——等一下,什么意思?

如果你映射一个文件,你可以直接访问该文件的内容,就好像该文件不知何故,神奇地,在你的程序地址空间中。对于只读访问,操作系统原则上只需要一页物理内存,每次访问不同的虚拟页面时,它可以用不同的数据重新填充(出于效率原因,这当然不是这样做的,但是原则上,您可以使用单页物理内存访问数 TB 的数据)。现在如果你写入文件映射?在这种情况下,操作系统必须有一个物理页面——或交换空间——为写入的每个页面做好准备。在脏页写回过程完成其工作(可能需要几秒钟)之前,没有其他方法可以保留数据。出于这个原因,操作系统保留(但不一定永远提交)交换空间,因此,如果您在写入映射时碰巧没有未使用的物理页面(这是一种很可能的正常情况),您再次保证它仍然有效。

现在如果没有交换怎么办?这意味着不能保留交换(duh!),这意味着一旦没有可用的物理页面,并且您正在写入页面,您就会以流程接收的形式获得惊喜分段错误,并且可能被杀死。

[/编辑]

然而,传统的建议将交换区的大小设为 RAM 的两倍是无意义的。尽管磁盘空间很便宜,但分配那么多交换空间是没有意义的。浪费便宜的东西仍然是浪费,而且您绝对不想不断地换入和换出数百兆字节(或更大)大小的工作集。

没有单一的“正确”交换大小(“正确”大小与用户和意见一样多)。我通常会分配一个固定的 512MiB,不管 RAM 大小如何,这对我来说效果很好。背后的原因是为512MiB的东西,你可以随时买得起的今天,即使在一个小的磁盘。另一方面,添加几 GB 的交换也没有什么好办法。您不会使用它们,除非出现严重问题。

即使在 SSD 上,swap 也比 RAM 慢几个数量级(由于总线带宽和延迟),虽然移动一些可能不再需要的东西来交换是非常可以接受的(即你很可能不会再次交换它,所以你的可用页面池实际上免费扩大了),如果你真的需要大量的交换(也就是说,你有一个使用例如 50GiB 数据集的应用程序),你几乎迷路了。

一旦您的计算机开始换入和换出千兆字节的页面,一切都将进入爬行状态。因此,对于大多数人(包括我)来说,这不是一种选择,因此进行那么多交换是没有意义的。

  • 拥有 8 GB RAM 和 8 GB 交换以及 16 GB RAM 和不交换有什么区别?如果您的计算机决定它需要 16.001 GB 的内存,它会不会开始清除/杀死相同的东西(但性能会在它开始发生之前下降)? (26认同)
  • @Mehrdad:这当然是有道理的。较慢的内存(交换)可以提高性能,因为“较慢”对于您很少或从不访问的事物无关紧要。通过将“冷”数据移出,交换有效地增加了可用于“热”数据的内存量。每小时只执行一次的守护进程或由默认加载但从未使用的内核模块分配的内存就是一个例子。您可以换出**那些**,或者您可以改为从缓存中删除页面。哪一个更好? (15认同)
  • -1 这个答案毫无意义。为什么速度较慢的内存(交换)会比相同数量的较快内存(RAM)具有更好的性能??在某些时候,您必须承认足够的 RAM 意味着不需要交换.. (12认同)
  • 完全不真实:内核不使用磁盘可能是一个优势,特别是如果您已根据规范配置了 OOM。如果 OOM 杀手被配置为处理您的清理工作,那么让它这样做而不是浪费磁盘空间和减慢您的机器速度是*有利的。* (7认同)
  • @NickT:交换不是为了更多的内存,而是一个危险信号,表明某些东西很快就会被杀死。我喜欢在杀戮之前有一个危险信号,而不是让一个过程“随机”在我眼前消失。 (5认同)
  • 如果较慢对于很少/从未访问过的东西无关紧要,那么将它交换到其他磁盘位置与在需要时从原始位置重新加载它有什么好处?我最感兴趣的是在这里看到你对@NickT 评论的回复——在某些时候,这个逻辑必须让位于数字——要么交换是无限的,并且永远不会执行 OOM 杀手,要么交换只会给某些人增加有限的空间有限大小的 RAM 池,无论如何都会执行 OOM 杀手。如果是后者,那么杀手在*之前*系统减速到爬行不是更好吗? (4认同)
  • @AF7 swappiness 设置永远不会影响 OOM 杀手是否运行(除非您将其设置为 0)。Swappiness 控制抢先换出进程页面以释放内存用于缓存/写入缓冲区。例如,在提取一些大的 tar 文件时,您有几分钟没有接触过 Firefox。使用`swappiness = 60`(默认值),每次在firefox 中执行某些操作时可能会很慢,直到相关页面全部重新调入。使用`swappiness = 10`,您可能不会注意到任何事情。但是递归 grep 可能必须访问磁盘,因为数据集太大而无法缓存。 (4认同)
  • 无论如何,`swappiness = 10` 左右是桌面的关键调整设置之一,因为这完全是关于响应能力,而不是真正的吞吐量。一个小的交换分区,比如 512MB 到 1GB 是有用的。它将允许分页出很长时间未触及的数据,从而为您的机器提供更多的 RAM 以供使用。保持物理内存绑定在启动时构建的一些数据结构 gnome-terminal 是没有意义的,但在它退出之前不需要触摸,或者直到你使用一些你从未使用过的菜单项。 (3认同)
  • @mikeserv:您有一个有争议的观点(“完全不真实!”),与著名专家的观点相反,但您当然有权获得该观点。此外,您做出了许多不正确的假设。例如,对于没有文件支持的“原始”数据,根本不可能从原始重新加载。此外,当交换发生时,系统_不会_缓慢地爬行,这只发生在您拥有相当大的活​​动数据集时(正如我在答案中指出的那样)。在正常情况下,交换几乎不会引起注意,如果有的话,例如...... (2认同)
  • @mikeserv:您假设有一个“需要”的数量。内核可以通过多种方式调度磁盘 I/O,在内存使用和性能之间进行权衡——通常更大的缓存 => 更好的性能(因为它可以避免多次读/写同一个块)。如果将很少使用的页面放在交换中,则内核具有更大的调度 I/O 的灵活性。正确的权衡将取决于您正在优化什么(数据吞吐量?请求/秒?延迟?响应感觉?等),但如果您的磁盘大于内存,则没有“内存过剩”这样的东西。 (2认同)
  • @mikeserv 如何杀死一个(半)随机进程来解决 DRAM 耗尽的问题?如果程序正在运行,那可能是有原因的。上次我经历过这种情况时,很多事情开始很快就崩溃了,随之而来的是数据丢失。对于这样一个系统来说,中等速度的内存泄漏将是非常可怕的,因为在它开始大量杀死很多程序之前你几乎不会收到任何警告。使用交换,您可能会注意到速度变慢,您仍然可以看到什么东西吃掉了所有的 RAM。 (2认同)
  • 我想不出任何原因为什么一台可以在 8GB 内存和 8GB 交换下运行良好的计算机在 16GB 内存和无交换下运行时会遇到问题。 (2认同)

mdp*_*dpc 50

我将不同意我在此处看到的一些观点。我仍然会创建一个 SWAP 分区,尤其是在生产环境中。我也为我的家用机器和 VM 做这件事。

这些天我将它们的大小调整为内存的 1-1.5 倍。2 倍内存曾经是经验法则。交换磁盘“便宜”,因为它不需要备份或保护。

如果您的内存不足,那么您的交换空间会给您一些时间和缓冲来解决问题。

意识到 /tmp 之类的东西可以驻留在交换空间中。

交换区可以保存部分内核转储,以便在下次重新启动时恢复。这对于您被要求执行的某些未来调试紧急情况可能会很好。

  • +1。交换意味着在低内存和硬崩溃下损害性能之间的差异。 (19认同)
  • “您的交换空间为您提供了一些时间和缓冲来解决问题”——这也意味着我必须在无响应的机器前坐更长的时间,直到内存泄漏“解决”自己。 (11认同)
  • @Davidmh:根据这个推理,您的交换文件必须无限大,否则您的程序在耗尽交换文件时仍会崩溃。 (7认同)
  • @mikeserv 无论您如何配置它,如果您的程序尝试分配比可用内存更多的内存,则某些内容会崩溃,或者操作系统将开始杀死它们。 (6认同)
  • @Mehrdad 但它也更贵。鉴于您有 X GB 的 RAM,因为这是您能负担得起的,对于一些合理的 Y 值(这将取决于您的使用情况和大小),它比拥有 X GB 的 RAM 和 Y 的交换区严格你的高清)。 (6认同)
  • @mikeserv:在我看来,不杀死应用程序比杀死它们更可取。 (4认同)
  • “1-1.5 倍内存”——当你的 16 GB RAM 机器交换 23 GB 时你会怎么做?等几个小时? (3认同)
  • 一个缺点 - 想象一下您的磁盘存储速度很慢。我正在考虑一个案例,我在 ISCSI SAN 上安装了带有 VM 存储的 vmware。SAN 通过 1GE 连接。我们有足够的 IOPS,但没有大量带宽。如果虚拟机由于应用程序失控而开始大量交换,唯一合理的行动方案通常是硬重启 - 登录速度太慢,无论如何服务器都被灌水。我们改变了一些东西,这样我们就有了小的交换分区,让 OOM 杀手更快地接管。 (2认同)

Eld*_*eek 25

也许:

我对这个话题进行了很多思考,看到争论双方的意见出现的次数多得我数不过来。我的方法是开发一种方法来找出答案。

从您认为足够大的活动交换分区开始。

然后,在工作区中打开一个终端并发出命令free -hs 1,该命令将每秒报告一次使用情况。

可选择切换到其他工作区。

做你可能会做的每一件事,然后再做一些。一次运行所有常用应用程序,浏览多个选项卡并拼命尝试为系统提供真正的锻炼,这可能意味着在运行编译操作和检查电子邮件或其他任何内容时重新编码 1/2 打视频。让我们面对事实,这完全取决于如何使用您的系统。

当您觉得系统处于高负载(或可能达到您可能达到的高负载,然后再高)时,请查看终端并检查结果。或者更好的是通过添加>output.txt到命令将输出重定向到文件,以便您可以检查完整运行。如果您使用的 Swap 从未超过 Mem free,则您不需要交换。如果是,你会。 免费.png

我不需要交换。也许你会。为什么不知道呢?

就大小交换而言,经验法则通常被高估,因为这是基于使用的问题。

  • @w3d 不,我不是这么说的。从上面的输出中可以看出,即使不需要,也会使用交换。这可以通过swappiness因子进行一些调整。我说的是交换与否的必要性。 (3认同)
  • 那么,您是说仅在您的系统绝对需要时才使用交换吗?在这种情况下,启用交换是否会受到惩罚 - 以防万一?其他评论似乎表明,即使存在交换也会对性能有害? (2认同)

AMA*_*nc. 18

注意:这发生在我身上,在一个特定的、不寻常的情况下。如果您正在对问题进行故障排除,这可能很有用。我并不是暗示所有机器都必须交换。

也许!

过去我曾遇到过我构建的运行 Linux 的“设备”的问题 - 在紧凑型闪存设备上运行,我不想通过使用交换来佩戴我的 CF,并且有足够的内存用于应用程序。

大多数这些设备运行良好,但在一个特别繁忙的盒子上,我遇到了一个问题:

内存碎片

没有交换空间,内存逐渐变得越来越碎片化,尤其是在长时间运行的进程中(尽管我有很多空闲内存,但都是很小的一点)。我放入了一些交换空间,并告诉 Linux 不要使用它,除非它必须;这完全解决了问题。

除了其他一切,交换空间还允许移动内存,对其进行碎片整理。如果您有碎片内存,并且您需要一个大块,则这些碎片将被换出;当它们被换回时,它们被有效地进行了碎片整理。

查看 /proc/buddyinfo - 我的现在看起来像这样:

Node 0, zone      DMA      9      5      3      4      2      3      2      2      3      3      1 
Node 0, zone    DMA32  33901   1149      0      0      0      0      0      0      0      0      1 
Node 0, zone   Normal   2414   1632    259     22      3      0      2      0      1      1      0 
Run Code Online (Sandbox Code Playgroud)

数字代表不同大小的块;每个大小是下一个块大小的一半,从左侧的 4mb 块到右侧的 4kb(即 4mb、2mb、1mb 等等)。新启动的机器应该在左边有所有的块,右边很少(= 没有碎片)。还要记住,相同数量的内存(例如 4mb)将在各列中表示为不同的数字 - 最左侧列中的 1 个块,最右侧列中的 1024 个。

内存从尽可能最右边的池中分配;例如,如果您的程序需要 12kb 的内存(一次性),它将从 16kb 列中获取;剩余部分将出现在 4kb 列中。如果没有 16kb 块,那么它将从 32kb 块中取出,导致剩下 16kb 和 4kb,依此类推。

如果没有足够大的内存块,并且您有交换空间,那么例如,如果您想要 16kb 的内存,它将找到最少使用的 16kb 块(例如,它可能包含一个 4kb 的已用块,一个 4kb 的可用块,和另外 2 个使用过的 4kb 块),将使用的部分仅移动到交换,并将释放的内存分配给新应用程序。

在崩溃的盒子里,我有成百上千的 4kb 和 8kb 块,其他的不多。

据我所知(通过崩溃的机器!)内核将从内存移动到交换,然后交换到内存,但永远不会从内存移动到内存。

  • 您的案例看起来很适合分配/实现大页面。它将避免碎片问题*(因为特定大小的巨页一旦分配,此后将永远仅以该大小再次分配)*。 (3认同)
  • 这是我读过赞成使用交换分区的最好理由。我尝试了一个快速搜索,但没有找到相关的参考资料,我想知道为什么这个功能没有被经常记录下来。 (2认同)

R..*_*ICE 17

您永远不应该让交换大于您能够容忍的等待内核换入/换出的最大大小;否则,您只是在为您的系统创建一个新的故障模式(在交换中无法恢复地陷入困境)。请注意,尽管现代驱动器能够以 GB/秒的数量级进行传输,但 Linux 通常只能以每秒数百 kB 或最多几 MB 的速率移动交换。如此巨大的交换会使您的系统在几分钟、几小时甚至几天内无法使用。

如果您有足够的物理内存用于您的工作,交换的理想大小是将其与保留但从未使用的“垃圾数据”进程的数量相匹配。这可能在几兆到几百兆的范围内。此策略允许您将所有物理内存用于缓存有用信息,而不是永久存储可能永远不会再次使用的数据。

如果您没有足够的物理内存,则需要评估您是否可以容忍大量交换造成的严重减速。如果是这样,最多 1-2 GB 的交换可能是有意义的,如果您有极快的驱动器,可能最多 4 GB。但除此之外只会使您的系统故障模式变得更糟,您应该考虑购买更多 RAM。

  • 我认为这是最好的答案。如果您有太多交换空间,则可能会由于所有交换而使机器完全无响应。这意味着你不能杀死有问题的进程。如果您减少交换空间,OOM 杀手会自动为您完成工作。关于文件缓冲区缓存的其他答案中的论点完全没有说服力。您应该有交换,以便内核可以将文件缓冲区移动到交换...这是在磁盘上?请。 (2认同)

Val*_*ity 15

交换分区具有重要的价值,而不仅仅是在您用完时充当一些额外的 RAM。

一方面,Linux 使用尽可能多的内存来缓存文件和 IO 操作,如果您有一些交换,您可能会发现更多的内存用于缓存 IO 并使其更快(通过最小化磁盘访问并降低 SSD 的磨损),而不是保存某些程序已分配但每 12 小时仅使用一次的数据,某些守护程序可能就是这种情况。

此外,Linux 使用乐观内存分配策略,即使不确定是否有实际内存来填充页面,它也允许名义上分配页面。这比进行适当的检查和映射每个分配更有效,并且通常不会导致问题。然而,内核用来确定允许分配是否合理的启发式方法包括系统上可用的交换级别,因此如果系统有足够的交换,分配可能会更快,即使它没有被使用太多。

这些因素共同使我个人认为,最好在几乎每个普通系统上进行一些交换,但是对于大内存,我忽略了 ram * 2 规则并简单地将交换限制在 4-8GB(取决于磁盘的大小) )。

  • 即使 4GB 对于台式机来说也太大了。如果出现问题,我宁愿在等待那么多交换填满之前激活 OOM 杀手。(如果我遇到需要更多虚拟内存的情况,我可以在运行任何需要比机器内存更多的虚拟内存的大型作业之前 dd 和 mkswap 交换文件。也就是说,如果退出我的网络浏览器没有足够的空间...) (12认同)
  • Linux 考虑可用交换空间的一种情况是当一个大进程试图启动一个子进程时:fork()+exec() 系统调用从粗略复制父进程的分配开始——内核不能保证新的子进程会更小比父母。通常不使用交换空间,但除非它可用,否则 fork() 可能会失败。客户端上的一个典型示例是浏览器启动插件,或者当大型应用程序容器调用帮助程序时在服务器上。1/2 或 1GiB 的交换通常足以解决问题。谷歌“java exec 无法分配内存” (3认同)

han*_*zer 11

仅当您希望能够休眠以进行交换时(此功能也称为“挂起到磁盘”,涉及保存 RAM 的全部内容并关闭电源)。通常,这仅用于笔记本电脑和其他移动设备,因此视情况而定。


小智 6

没有通用且明确的答案,因为这取决于您将要执行的任务。如果您要运行数据库、HTTP、虚拟化或缓存服务器,无论您拥有多少内存,都不应启用任何类型的交换。如果您有台式机或混合任务主机,并且拥有 16 Gb 以上的快速 RAM - 请查看此处:zRam


jll*_*gre 5

如果我们知道的唯一参数是安装的 RAM 量,则无法判断您是否需要交换空间。

在任何情况下,都有一个普遍的误解,即拥有交换空间会对系统性能产生负面影响。这是不正确的。只要您有足够的 RAM,无论大小如何,交换区域都不会影响性能。影响性能的是 RAM 不足和有效使用交换空间。

  • 情况 1:如果您没有交换空间并且碰巧内存不足,Linux 内核将选择一个或多个它认为合适的进程并杀死它们。

  • 情况 2:如果您有一个交换空间并且内存不足,内核将挑选较少使用的内存页面并将它们放在交换区域以释放 RAM。这会减慢系统速度,但您的应用程序不会受到其他影响。

我总是喜欢情况 2,因为我觉得丢失部分或全部工作不舒服,因为内核认为我的应用程序值得杀死。此外,由于当前平均磁盘的大小在 TB 范围内,因此为交换保留几个百分比应该不是问题。

  • 我更喜欢第 1 种情况,因为只有当我有一个失控的程序时,我才会用完 RAM。OOM 杀手通常非常擅长识别失控者,我真的宁愿立即将其杀死,也不愿经过几个小时的大量交换后将其杀死。 (6认同)
  • 情况 2 仅当您有一些警告您有关这种情况的内容时才有效,并且有足够的时间在系统用完交换之前手动“做某事”。但是您可以改为监视已用 RAM 的百分比以获得相同的结果。 (2认同)