当 Linux 有交换而没有交换时它可以做什么?
对于这个问题,我想关注例如具有 32 GB RAM 且没有交换的 Linux PC 与具有 16 GB RAM 和 16 GB 交换的几乎相同的 Linux PC 之间的区别。请注意,我对“是的,但是如果将交换添加到 32 GB PC 可以看到 X 改进”不感兴趣。这是这个问题的题外话。
我第一次遇到这样的观点,即添加交换比在早期问题的注释中添加 RAM 更好。
我当然读过这个:如果我有足够多的 RAM,我需要交换空间吗?和...
- 答案主要集中在添加交换上,例如讨论磁盘缓存,其中添加 RAM 当然也会扩展磁盘缓存。
- 有人提到只能通过交换进行碎片整理,但我找不到支持这一点的证据。
- 我看到一些对 MAP_NORESERVE 的引用
mmap
,但这似乎是一个非常具体且晦涩的风险,仅与OOM情况相关,并且可能仅与私有mmap 相关。
交换通常被视为扩展内存或提高性能的一种廉价方式。但是,当大规模生产嵌入式 Linux 设备时,情况就发生了翻天覆地的变化……
...在这种情况下,交换会磨损闪存,导致它在保修期结束前几年失效。将 RAM 翻倍是在设备上多花几美元。
请注意,这是 eMMC 闪存而不是 SSD!. 通常 eMMC 闪存没有磨损均衡技术,这意味着它的磨损速度比 SSD 快得多
在这件事上似乎有很多激烈的争论。我真的在寻找关于能力的枯燥事实,而不是“你应该/不应该”的意见。
通过添加 RAM 也无法完成的交换可以做什么?
休眠(或挂起到磁盘)。真正的休眠会完全关闭系统,因此 RAM 的内容会丢失,您必须将状态保存到一些持久存储中。又名交换。与使用
hiberfil.sys
and的 Windows 不同pagefile.sys
,Linux 将交换空间用于过度使用的内存和休眠。另一方面,要在 Linux 上正常工作,休眠似乎有点挑剔。您是否“可以”实际上休眠是另一回事。¯\_(ツ)_/¯
像这样问,交换主要是省钱,提高每美元的性能比,也许还有每瓦特。
但是交换仍然不仅仅是“像磁盘一样慢的内存”。它是内存页面的临时存储,可以在需要时直接(虽然它们很脏,没有文件系统开销)加载到 RAM 中。
当然,很大程度上取决于负载(负载的类型),交换的想法甚至会适得其反。
swapon
这就是为什么除了/本身之外还有“swappiness”参数,swapoff
以及关于正确大小的讨论。从维基百科我得到了关于 linux 中“交换”的声明(在“分页”文章中)
这表明您可以将交换变成在硬件级别上更有意义的东西:专用的“暂存驱动器”将为这些换出的页面提供更好的归宿。理想情况下,暂存驱动器应该(非常)小但快速且坚固。
根据“新”大小规则(千兆的平方根),您的示例应该比较:
16 GB RAM
+0 GB Swap+1000 GB Disk
16 GB RAM
+4 GB Swap+ 996 GB Disk
因为真正没有意义的是:
16 GB RAM+0 GB Swap
+1000 GB Disk
12 GB RAM+4 GB Swap
+1000 GB Disk
那将是 tmpfs(“ramdisk”)上的交换分区 - 甚至可能不会太有害,但我在这里看不到任何好处。你甚至不能冬眠。
(但是,当您向其添加压缩时,请参阅下面的 zram 和 zswap )
要了解交换您必须考虑整个系统和平均负载。而且因为 vm/mm(虚拟内存管理)是一个复杂的系统,所以很难说出一个明显的优势。我喜欢“平滑”过渡到过载系统的想法。
我有 8 GB RAM,没有交换。但我仍然捍卫这个概念,AFA 我能理解 :-)
我在其中一个 OP 链接中找到了这个 redhat 引用。如果我记得的话,场景是在 2 GB RAM + 2 GB Swap 上不断增加的内存需求:
但替代方案
OOM
更早!是的,“性能不佳的时间”很长,但性能只会与负载成比例地下降。我不知道上下文,也许他们只是想警告交换分区太大。这听起来是反互换的,但仔细一看却不是。
再说一次,出于同样的原因,我没有交换。我想知道我和我的应用程序何时达到上限,然后我将决定是否必须减少负载、购买更多 RAM 或激活用于交换的分区(我为此准备了一两个小分区)。
我查了这个zram,然后查了zswap的东西:非常有趣...:
另一方面,
zram
无需任何交换设备即可工作。这使得我所说的没有意义,但我没有考虑到压缩。我的观点是“交换”中固有的这种驱逐机制。这在高负载下非常有用,无论您是通过换出还是通过压缩进行交换。
这个问题实际上可以改写为非易失性 RAM 可以做什么,而添加更多的易失性 RAM 也不能做到这一点?. 仅仅因为您碰巧将一个分区专用于分页(一种与易失性 RAM 交互的专用方式),它并不会改变它仍然是持久性辅助存储介质的一部分的事实。交换分区对于使系统进入休眠状态也不是强制性的,也可以使用在预先存在的分区上创建的“交换文件”。
最后,无论您使用的是交换分区还是交换文件,您将存储的是要写入 RAM 或从 RAM 写入的内容。如果您要从启用了交换分区的系统中拔出电源线,则该交换分区不会被神奇地擦除。
虽然在您下次启动时不会读取此交换数据(因为分页文件将包含与不再运行的进程相对应的条目),并且某些发行版可能会在正确关闭或正确重新启动期间采取有意的步骤来销毁它,如果有人从系统中拔出一根绳子,他们将能够取证检查该交换分区。
就您提到的嵌入式设备而言,闪存作为一种非易失性 RAM(NVRAM 或 EEPROM)存储,由于其承受 I/O 命中的能力(闪存单元耐久性以程序数量表示)而磨损/erase 周期)与易失性 RAM 相比相形见绌。每次写入该位置时,您实际上都会刮掉一层氧化物,最终根本没有氧化物可用于持久存储电荷,并且在随后的读取之前它实际上会泄漏出来。
另一方面,与闪存相比,如果或当您切断其电源时,volatile 的 RAM 的生存能力几乎不存在(在理想的实验条件下约为几分钟)。在易失性 RAM 的情况下,没有什么可以阻止电荷泄漏和触发器的相应状态(输入、确定输出,然后重新确定输入),也就是反馈控制的锁存器。
对于给定的总数,将其作为 RAM 总是比交换更好。
noswap 系统和交换系统之间的行为存在差异,这可能有用也可能没有用:抖动。随着交换系统开始耗尽总可用虚拟内存,它在交换和 RAM 之间来回移动页面时变得越来越阻塞。这会减慢系统速度。在某些情况下,这可以允许手动或自动干预以减少负载并恢复系统。
在 noswap 系统中,性能保持相对水平,直到内存使用率非常高,此时操作系统开始从内存映射的可执行文件中卸载只读页面,并且磁盘缓存的空间也很小。此时很可能会触发OOM杀手。所以是突然的失败而不是缓慢的退化。
我同意交换对嵌入式系统意义不大,尤其是在小型嵌入式闪存设备中。世界上到处都是小型 Linux 消费者路由器、灯泡等,内存使用量相当固定且没有交换。
与 RAM 不同,交换可以轻松禁用、限制、减慢或扩展——在开发应用程序的内存分配策略时这是一个有用的功能。
假设您的内核看到 4G 的 RAM 和 4G 的交换空间,而操作系统和开发应用程序(浏览器、IDE 等)消耗 3G。那是 5G 免费虚拟:1G 真实和 4G 交换。
你正在开发你的新数据库或游戏,它想要说 2G 来加载它的热资源。所以它一直在进行,
sbrk
并且mmap
反复进行,并且通过交换打开,通过内核的 VM 层的奇迹来获得它的 2G 真实。万岁,你的代码运行良好。(还有你的浏览器或任何被页面降级为交换地狱的东西。)现在,停止你的程序。
swapoff
并重新运行您的程序。这一次,当它开始sbrk
咆哮时,它得到了一个ENOMEM
并且你的代码必须处理一个不愉快的路径。它如何反应?在这种情况下它是如何跳舞的?或者挂载一个 U 盘,
mkswap
然后swapon
在 U 盘上挂载,并增加vm.min_free_kbytes
以强制内核更多地转到那个 U 盘。重新运行您的程序。您的应用程序现在在缓慢分配 VM 的情况下表现如何?在您的应用程序运行时执行上述所有操作怎么样?它在运行并开始遇到 OOM 条件后表现如何?
您可以通过实时调整交换子系统来折磨在可用真实 RAM 上运行的系统的方法没有尽头。与 cgroups 或 rusage 不同,您不必关闭进程来更改可用的虚拟 RAM。
你可以对这些内存滥用进行测试,使用 mocks 来模拟
ENOMEM
或 slowbrk
,这是一个合适的做法,因为它是稳定的。但是,没有什么比在低内存环境中进行实弹练习更能挖掘随机过程的黄金了。Swap 让测试人员可以在运行中轻松地调整内核的内存资源和特性,其方式与低内存的现实世界非常相似。添加或移除 RAM 棒不会提供此值。这是一个小众案例,诚然你可以添加更多的内存,但是......
每个人似乎都认为交换意味着物理的非易失性存储,如硬盘驱动器或闪存驱动器。交换更多的是一个过程,而不是物理位置。
考虑以下奇怪的恶作剧:
交换的用途(恰好在 RAM 中),这不仅仅是从普通 RAM 中获得的(其中没有交换分区)。
虽然,是的,但从技术上讲,您可以添加更多内存;这种奇怪意味着无论你添加多少内存,你总是可以争取更多的空间(只要你知道你的数据/任何合适的)。
休眠需要一个交换文件,即使没有以其他方式使用交换。
除此之外,什么都没有。掉期是一个很好的权宜之计,如果
与磁盘空间相比,RAM 非常昂贵或有限
该系统是由 1 个用户控制的通用系统,该用户可能会不时尝试不可预测的软件和/或工作负载。
如果 OOM 场景完全可行,并且分页到磁盘比程序彻底崩溃更可取。
两件事情:
A. 当 RAM 已满时在场。
B. 保留在给定时刻实际上没有被进程使用的内存页面(因为它们在某些情况下被阻塞)以允许 RAM 用于其他用途。
如果您有足够的 RAM 来满足将同时运行的所有进程的任何内存请求,或者不介意 OOM 错误,则可以忽略 A。
Linux 使用空闲 RAM 来缓存块设备读取和写入,但并非必须如此。RAM 比块设备快。允许 Linux 分页出进程不用于交换的内容将允许使用更多 RAM 来缓存块设备读取。如果您不关心块设备访问的速度,它可以应用于路由器等嵌入式环境,则可以忽略 B(在这些情况下,您无论如何也不关心休眠)。
交换不是磁盘缓存 - 交换中的页面可能不与磁盘文件关联或从未打算写入磁盘。
你已经有了答案,但你的问题表明你还不欣赏这个答案。
简单的答案是,“大而便宜(也许灵活)”。你已经知道了,但你也忽略了它。你不应该。
RAM 不是“几块钱”。例如,我服务器上的 ECC RAM 对于 32 GB (RDIMM 2400 DDR4) 的价格为 130 英镑,或大约为 4 英镑/GB。我用于交换的 SDD 每 TERABYTE 的成本约为 100-130 英镑,或约 0.11 英镑/GB(具有断电保护的美光/英特尔)。服务器场每台服务器可能需要数百到数千(在许多情况下)GB,有数百台服务器。
RAM 也更耗电——RAM 中的空闲进程需要 RAM 供电和刷新,而在 SSD 上,耗电量要少得多。在小型嵌入式设备上,这本身就是一个问题。
在大多数设备上,磨损均衡问题也比您想象的要小。SSD 的使用寿命比人们想象的要长,商业设计的设备会选择 SSD 来匹配他们的预期用途,而不是某些卡中极差的 SSD。
最后,Swap 更灵活。如果您的任务通常使用 32 GB,但它的某些方面很少需要 64 GB,那么无论如何您都必须提供 64 GB。使用交换它可以在 32 上工作,并在特殊时期短暂使用,然后丢弃,交换。
Tl;博士 - 你完全错过了经济点。
Swap 可以帮你省钱。RAM 比相应数量的磁盘更昂贵。目标是优化性价比。当然,RAM 总是比交换好,但如果你不使用它,它会花费更多,而且会浪费掉。
交换的有用性也很大程度上取决于工作负载的类型。例如,如果您打开了很多应用程序,但主动只使用其中一个,则非活动程序使用的 RAM 可以被释放,而由活动进程使用。另一方面,使用需要比可用 RAM 更多的内存的单个内存密集型程序是交换的非最佳使用。
我想你会发现这是错误的。首先,额外的几美元不会使任何合理数量的 RAM 翻倍。其次,闪存比 RAM 便宜。第三,交换用于非活动数据。如果您遇到交换分区被连续写入的情况,那么您的 RAM 太少,如果没有交换,一些重要的进程就会崩溃。
此外,对完整 SSD 的随机写入(这会导致它们提前失败)很慢。它们确实非常非常慢。如果您的计算机没有因交换而减速到爬行状态,您的 SSD 就不会过早死亡。
当你的计算机内存不足时,它明显变慢比某些重要进程崩溃要好得多。
现在,你可以用 RAM 做的交换来做什么?