交换是不合时宜的吗?


43

我已经使用unix一段时间了,在最近几年中,我觉得交换是不合时宜的,但是我很好奇其他人的想法。

我的说法大致是这样(假设没有全局ulimit或OOM设置的混乱):

There is little value in swap because if you need to swap out to disk, 
odds are it's going to be a vicious cycle where an app will continue 
to eat not only real memory, but swap as well until it gets OOM 
reaped (_if_ it gets OOM reaped). 

If you have swap enabled, it will only prolong this death march to 
the detriment of other processes - and in the worst case where the
process is not OOM reaped in a timely manner, grind the system to
a halt.

Without swap, it will probably get OOM reaped sooner (if at all)

对于任何针对性能进行了调整的服务,我认为了解其资源使用的上限对于首先进行调整至关重要,在这种情况下,您便知道需要多少资源。

我无法想象在许多情况下(某些但不是很多),您会挂起正在运行的进程,并且该进程可能会交换以腾出空间来容纳其他事物,但是如果这样做,您仍然会丢失套接字,因此强制执行通过gcc进行核心转储或手动复制内存在功能上是等效的。

我绝对不希望在嵌入式系统上进行交换(即使它可能具有较小的可用RAM),如果用完了RAM,我宁愿让我的进程死掉,也不愿破坏每扇区一百万个写入的闪存在整个周末内将各个行业的平均水平降至平均水平。

那里有没有胡须的人有充分的理由进行互换?

更新答案和分析:

  • 确认?-fork()对于子进程需要与父进程相同的内存量

    现代的fork()通常是在POSIX 用于子代的写时复制,但是专门针对LinuxFreeBSD,我通过推断来假设OSX。我认为这是随身携带的过时行李的一部分。

    奇怪的是,这篇Solaris文章声称,即使Solaris通过fork()使用写时复制功能,您也应该在空闲虚拟内存中至少有2x(!)的父进程大小,以使fork()不会被废除。中间。尽管Solaris元素在某种程度上消除了交换是不合时宜的说法,但我认为,足够多的操作系统正确地实现CoW的方式是,消除神话比将其标记为交换的进一步理由更为重要。以来。面对现实吧。此时,实际使用Solaris的人可能只是Oracle。没有冒犯Solaris!

  • 确认 -当tmpfs / ramfs填满时,tmpfs / ramfs文件可以方便地交换

    不要使用无限制的tmpfs / ramfs!始终明确定义要tmpfs / ramfs使用的ram数量。

  • 可能 -稍作交换以防万一

    我的一位老老板曾经说过一句好话,“你不知道你不知道什么”-本质上,你无法根据尚未掌握的信息做出决定。这是交换给我的一个合理的论点,但是-我怀疑您要检测应用程序是否交换出的内容比检查malloc()是否成功或从中捕获异常要重得多。失败的new()。

    如果您正在运行台式机并且发生了许多随机事件,这可能会很有用,但是即使如此-如果出现问题,我还是希望OOM能够收获而不是陷入掉地狱的境地。这就是我。

  • BUS!-在Solaris上,由于以下几个原因,交换重要

    tmpfs-状态tmpfs 可用的可用空间量取决于系统中未分配的交换空间量。tmpfs文件系统的大小会增加以容纳写入其中的文件,但是对于tmpfs的大量用户来说,存在一些固有的折衷。Tmpfs与执行程序的数据段和堆栈段共享资源。如果tmpfs文件系统接近其最大允许大小,则可能会影响大型程序的执行。Tmpfs可以自由分配系统的4MB交换空间以外的所有空间。

    关于交换的Solaris事实和神话 -状态当今的虚拟内存由物理RAM和磁盘上交换空间的总和组成。Solaris根本不需要配置任何交换空间。如果选择此选项,则RAM装满后,将无法启动新进程。

    我不确定这是否意味着您可以创建的最大虚拟地图是ram + swap,还是仍然可以像mmap()这样的文件来做比ram大的文件,并依靠mmap()的延迟初始化。可以在没有交换的情况下很好地运行Solaris,这似乎不如其他POSIXy操作系统友好。

  • BUS!流行的Linux休眠工具似乎依赖于交换

    默认情况下,尽管存在其他后端,TuxOnIce看起来像依靠交换进行休眠。但是,如果您没有运行需要休眠的机器,我仍然会支持“交换在Linux上是古旧的”的说法。


我没有太多的**胡须(仍然有些毛发;),但是我的2美分将是拥有“少量”交换将使您的系统更坚固。与直接使用OOM相比,如果超出系统限制,则应改为交换。当然,如果确实超出系统限制,您的系统最终将崩溃/停止/自行核弹/您能想到的一切。所以给一点玩耍的机会吧;)
Ouki 2012年

1
如果将系统设置为永不过量使用RAM,则fork()的事实实际上是正确的(这不是默认设置)。现在为什么您将不再需要该设置了,我不知道了。它对于实时处理没有用。
2012年

@Jushua:内存过量使用可能不是默认的,甚至可能不是,具体取决于操作系统。
jlliagre 2012年

我有一台具有8GB RAM的NAS服务器,它将最多可运行2个VM。我没有把交换。如果它开始大量交换,那么它已经死了。因此,它完全支持您的论点。另一方面,我仍在使用生锈的台式机,其内存限制为1GB,在那里我确实可以交换来处理稀疏的内存。它使速度变慢,但可以帮助我同时打开Firefox和其他应用程序。
惠更斯州

我发现只有在清空所有缓存并且系统变得缓慢之后,OOM杀手才会触发。为了使系统保持快照,我使用Earlyoomnohang来做同样的工作,但是要更早!可与或不与交换一起使用。
joeytwiddle

Answers:


28

不要混淆(作为磁盘区域的)交换和(作为)将内存页从RAM相互移动到磁盘的方法的交换。

出于性能方面的考虑,应避免过度交换,但是拥有交换区域并不一定是问题。

在像Linux这样的系统上,内存过量使用(即允许进程分配的内存超出可用内存),用完RAM且没有足够的交换空间来处理这种情况将触发OOM杀手er。您必须信任用于选择要杀死的“正确”进程的算法,并接受一个或多个要杀死的进程,而没有机会正确关闭。这是一个著名的类比,解释了为什么OOM杀手可能根本不是一个好主意。

在像Solaris这样的系统上,不要过度使用内存,即确保始终由虚拟内存支持内存预留(无论是在RAM还是在磁盘上),都必须有足够的交换区域,否则将可能会占用RAM的很大一部分浪费了。


1
您确定有关Solaris的观点仍然正确吗?blogs.oracle.com/jimlaurent/entry/solaris_faq_myths_and_facts指出:今天的虚拟内存由物理RAM和磁盘上的交换空间的总和组成。Solaris根本不需要配置任何交换空间。如果选择此选项,则RAM装满后,将无法启动新进程。我想我明白您的意思是-如果您想在没有交换的情况下映射比物理内存更大的东西,您将无法做到?(不管mmap是一个惰性初始化程序)。
synthesizerpatel

5
是的,我确定我对Solaris的观点仍然正确。即使Jim Laurent的报价是正确的,即Solaris不需要交换,但没有交换意味着即使不使用某些分配的内存,所有内存保留(即malloc)也需要由RAM支持。这与大型mmap或tmpfs无关,尽管tmpfs也是您可能希望与Solaris(以及Linux进行交换)的原因。
jlliagre 2012年

1
Linux更新:可以关闭过量使用,可以修改OOM算法,甚至可以使用cgroups拥有自己的OOM处理程序。
彼得

1
@peterph在Linux上关闭过量使用将交换变得不合时宜。如果您不超量使用,则必须确保有足够大的交换区,以支持所有保留。
jlliagre

1
fork保留的虚拟内存取决于执行此操作的程序的大小。假设您有一个使用2 GB内存派生的Java VM,它将临时需要2 GB以上的内存。如果在您的2 GB可用空间较少或同时发生多次的情况下发生这种情况,则一个或多个fork将失败。对于非过量使用的OS,以及在禁用过量使用的Linux中,这都是常见情况。通过具有足够大的交换区域,可以很容易地修复它,IMHO比内存过量使用是一个更好的解决方案。
jlliagre

3

我知道保持互换的原因之一。我有一个应用程序会占用我为系统配置所需的尽可能多的内存。它使用Hadoop,它在处理的一部分执行fork和exec来运行单个unix命令(我认为“ uname”或“ user”或他们找不到与Java等效的东西)。看来Java不会像本机应用程序那样对写语义上的副本执行vfork。如果我使用4Gb RAM启动应用程序,则在派生时,派生会使用另外4Gb RAM,但随后会快速释放它。如果我没有Hadoop可以交换到的4Gb交换空间,那么我将不得不为8Gb RAM付出代价,而我的应用程序只有4Gb。


这是一个好点,但不是现代fork()的体现-在Linux和FreeBSD(表面上是OSX?)上,fork()是通过使用写时复制页面实现的。写时复制(或COW)是一种延迟或完全阻止数据复制的技术。父级和子级可以共享一个副本,而不是复制进程地址空间。但是,对数据进行标记的方式是,如果将其写入,则会进行重复,并且每个进程都会收到唯一的副本。引用:forums.freebsd.org/showthread.php?t=26355和fork()的Linux手册页
synthesizerpatel

虽然为true,但有些页面无法标记为COW。例如,用于新的子进程的内核堆栈,并用于内部数据结构(该页面的页面files_struct中,struct signals中,task_struct和其他)。而且,许多可执行页面不是位置相关代码(PIC),因此ld-linux.so即使没有立即写入任何内容来交换空间,由动态加载程序()修改的可执行代码页面也必须为其保留交换空间。这就是为什么我喜欢Linux。您可以关闭交换,系统仍然可以运行。:)
Azhrei 2015年

3

从技术上讲,我无法添加讨论,但我可以举几个例子。我的旧笔记本(2GB RAM kunbuntu lucid)通常在交换位置为0时运行。当我运行传输(bittorrent客户端)时,带有许多可以总共使用100个连接的torrent,我的交换可以增加。当我运行使用1GB实际内存的XP虚拟机时,情况甚至更糟。

我看到其他人评论说,诸如图形渲染之类的内存密集型进程也可能陷入交换。如果您只是偶尔这样做,那么这不是问题。

就OOM问题而言,交换实际上可以挽救生命,因为它可以使您在确定问题和解决问题之间花费时间。很多事情几乎占用了我的全部内存,因此我对此没有任何注意,但是当swap开始运行时,我注意到了这一点并开始寻找问题-在它被我咬之前。


是的,没有启用交换功能,旧系统就无法做很多事情。我仍然有一个带有256MB RAM的旧子笔记本,其中需要swap才能启动几乎任何程序。我相信这个问题是针对现代系统的。
德米特里·格里戈里耶夫

3

交换空间有一个非常不错的应用程序:通过将交换空间放在使用RAM的存储设备上来扩展RAM,以克服可安装系统RAM的限制

看看这个繁琐的文章http://techreport.com/articles.x/16255 它基本上是从S-ATA到DDR2-RAM的接口。您最多可以在其中填充64GB RAM。通过在其中之一上放置交换空间,您将获得大量的额外RAM。当然,它不如常规系统RAM快。但这会将系统RAM变成某种额外的缓存层。


1
考虑到它的价格(549美元),在支持64GB RAM主板上投资100美元不会更有效吗?
德米特里·格里戈里耶夫

1
@DmitryGrigoryev:当然可以。但有时您不得不使用那种特殊的硬件(由于咳嗽而导致医疗系统认证不佳),而且还不得不处理在极短的时间内生成的可笑的大型数据集(想像断层扫描仪,数据速率> 3GiB / s)。
datenwolf

在这种情况下,您是否也不必将RAM驱动器认证为医疗设备?;)但是,是的,我明白了。
德米特里·格里戈里耶夫

1
@DmitryGrigoryev:确实,您必须这样做。但是,认证这样的S-ATA RAM磁盘设备比认证整个主板容易得多。在采购用于医疗设备的计算机时,通常会购买尽可能多的经过认证的现成部件。对于那些没有任何可用认证的零件,您可以自己进行必要的测试和认证。尤其是在研究时,重点放在患者的安全性上,并且数据没有用于治疗计划,这是最经济高效,最快的解决方案。BT; DT。
datenwolf

3

我一直在具有4Gb或更大容量的笔记本电脑/台式机上运行Linux 和Windows,而没有交换(在Windows文件中为分页文件)。在某些情况下,发生内存耗尽时,我会处理它们。我觉得系统更灵活,这是我更关心的。我对工作量没有特殊要求。

我学到的东西:

  • Windows会随着时间的流逝而“丢失”内存,在大约20-30天的正常运行时间中,到了我更喜欢重新启动的时间。我不知道为什么会这样。我猜这可能是某些驱动程序或防病毒程序泄漏。当您有分页文件时,我相信它可以将泄漏的内存放入分页文件中,因此在常规Windows系统上很难注意到此问题。
  • Firefox占用很少的内存,比Chrome处理得更好。Firefox会警告您并仍在运行,Chrome只是崩溃了。

2

我认为您的论点对于服务器(在性能很重要的服务器)上是非常有效的,知道下一步将执行哪个应用程序可能无法预测。

但是,对于台式机,当我推送和弹出任务时,我发现交换很有用。

例如,如果我正在使用应用程序执行任务A,然后发现需要使用应用程序B执行某些操作(子任务或中断),那么A在工作时我就更容易让我交换到磁盘在B比关闭A,然后记得以后再次启动它。

如果A保持一些未保存状态,则在重新启动时无法恢复,尤其如此。

推入A/ 拉出/ 拉出交换的速度更快还是关闭并重新启动它取决于应用程序。(有些人启动速度较慢,但​​居住面积较小。)

但是,我同意提高生产率的更好解决方案是安装一些额外的RAM。


更新:写下此答案后,我拥有一台笔记本电脑,其中包含大量RAM和缓慢的硬盘驱动器。在这种情况下,我的建议就相反了!这是优点和缺点摘要
joeytwiddle

1

在我的系统上,如果/ tmp吞噬了过多的RAM,则会溢出以进行交换。

这比将真实文件系统用于/ tmp快得多。


这非常危险-如果我需要ramfs,可以在fstab(或选项)中指定以显式设置大小。程序可能会因内存分配而疯狂地进行ape-crap,就像它将开始在/ tmp中创建文件一样。交换可能是ramfs文件无法显示的地方(特别是如果您依靠ramfs来提高速度)
synthesizerpatel

2
我经常超过那里的RAM大小。即使发生溢出,由swap支持的tmpfs也比ext2快得多。
2012年

有用的知识-可能是将来要研究的研究项目-我仍然担心应用程序会通过/ tmp中的tmpfs / ramfs代理填充我的ram。那给了我暴走的吉卜赛人!
synthesizerpatel

然后设置限制=交换大小。
2012年

顺便说一下,这是ramfs和tmpfs之间的区别。tmpfs可能会溢出以进行交换,而ramfs无法。
2012年

1

使用交换时有很多原因。

通常,当系统没有足够的物理内存时,内核可以将某些应用程序(实际上-未运行的应用程序使用的某些内存部分)进行交换。

稍后,当这些应用程序应该执行某些操作(例如,某些数据到达套接字或某些计时器触发)时,内核会将其他应用程序交换。

交换使用的另一个示例是挂起到磁盘。

关于嵌入式设备,可以将它们全部分为(至少)两个大类:

  1. 他们运行Linux / Windows或类似的非RTOS(实时操作系统);要么
  2. 他们运行一个RTOS。

当然,有些设备只运行某些代码(某种微控制器)等。我不会描述它们,因为此类设备没有任何操作系统,因此讨论交换对于此类设备毫无意义。

第一组嵌入式设备(运行某些OS)可以使用(通常使用)交换。通常,此类设备以与台式机和服务器相同的方式使用交换。

第二组设备(运行RTOS)根本不使用交换,因为RTOS对事件做出响应的时间有所限制,并且

  • 从交换读取可能会花费不可预测的时间
  • 设备具有预定义(在编译时)数量的任务,无需交换

顺便说一句,关于Linux如何使用交换的描述很多,其中之一是 http://distilledb.com/blog/archives/date/2009/02/22/swap-files-in-linux.page
Windows使用类似的方法。


另外,除非您使用的是TuxOnIce之类的东西,否则休眠(挂到磁盘)都需要交换。
雷南

1

在我看来,休眠和混合睡眠都需要在Linux上交换空间

在遇到需要使用Hybrid Sleep的需求之前,我从未在Linux上使用交换空间/分区-因为在我的系统上无法使用关键电池电量的睡眠,这是由Upower处理的,Upower仅在Shut-Down,Hibernate和Hybrid之间进行选择。 -睡觉。(更多在这里


0

我已经看到一些很好的用法,这些过程会占用大量内存,但对性能并不重要。一个例子是一个古老的Firefox,它的内存泄漏很严重。它将填满RAM并溢出以进行交换,而不会产生不良影响。我们拥有的另一个是递归DNS服务器(那些服务器迅速建立了一个很少使用的巨大缓存)。

我看到的关于交换的另一种解释大致上是这样的:“被告知始终配置SWAP = 2 * RAM。这完全是胡说八道,RAM和交换之间没有关系。交换是为了适应内存使用量的峰值,您应该添加足够的内存,以便大部分时间将负载装入RAM。如果负载稳定,则不需要交换;如果负载变化很大,则需要足够的交换以适应尖峰,并安排总而言之,由于您不知道负载峰值是多少,并且磁盘比RAM便宜得多,因此请配置SWAP = 2 * RAM。

某些Solaris的旧版本根本不使用交换,除非交换至少与RAM一样多(我记得它为退出RAM或类似的东西分配了固定的交换空间),因此2 * RAM确实在最小限度内值。但这是在不久之前,当时我们的大型计算机具有64个MiB RAM和1个GiB磁盘...

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.