当仍有“非活动”内存时,如何禁止 Mac OS X 使用交换?

当仍有“非活动”内存时,如何禁止 Mac OS X 使用交换?

在我日常使用 OS X 的过程中(以及根据互联网上的各种帖子,还有其他几种情况),一个常见的现象是,只要没有更多“可用”内存,系统似乎就会变慢。据推测,这是由于交换引起的,因为显然磁盘活动很繁重,并且 vm_stat 报告了许多页面调出。(请纠正我的错误)

然而,当交换开始/发生/结束时,“非活动”内存的数量通常约为所有可用内存的 12.5%-25% (^1.)。

根据http://support.apple.com/kb/ht1342

非活动内存

内存中的这些信息并未被主动使用,但是最近被使用过。

例如,如果您一直在使用 Mail,然后退出,则 Mail 使用的 RAM 将被标记为非活动内存。此非活动内存可供其他应用程序使用,就像可用内存一样。但是,如果您在其他应用程序使用 Mail 的非活动内存之前打开 Mail,Mail 将打开得更快,因为其非活动内存已转换为活动内存,而不是从较慢的硬盘加载 Mail。

并且根据http://developer.apple.com/library/mac/#documentation/Performance/Conceptual/ManagingMemory/Articles/AboutMemory.html

非活动列表包含当前驻留在物理内存中但最近未被访问的页面。这些页面包含有效数据,但可能随时从记忆中释放

因此,基本上来说:当程序退出时,其内存将被标记为“不活动”,并且应可随时认领。不过,每当“可用”内存不足时,OS X 都会选择开始将内存交换到交换文件,而不是仅仅认领这部分内存。

为什么?这种行为与立即释放非活动内存甚至不接触交换文件相比有什么优势?一些来源 (^2.) 表明 OS X 会在释放“非活动”内存之前将其换出进行交换,但这现在没有意义了,如果内存可能随时从记忆中释放? 交换很贵,释放很便宜,对吧?

可以使用某些偏好设置或已知的 hack 来改变这种行为吗?(最好不包括完全禁用 swap/dynamic_pager 并重新启动...)

我很感激清除命令,以及修复磁盘权限以强制释放一些内存的概念,但这些都是痛苦地强制释放更多内存的方法,而不是真正修复交换/释放决策逻辑......

顺便说一句,这里有人问过类似的问题:http://forums.macnn.com/90/mac-os-x/434650/why-does-os-x-swap-when/和这里:http://hintsforums.macworld.com/showthread.php?t=87688但尽管原帖作者重新提出了核心问题,却没有任何回复能够给出答案...

^1。更新日期:2012 年 3 月 17 日自从我第一次发布这个问题以来,我已经将安装的 RAM 从 4GB 升级到了 8GB,但问题仍然存在。之前“非活动”RAM 的数量为 0.5GB-1.0GB,现在在交换开始/发生/结束时通常约为 1.0GB-2.0GB,也就是说,似乎 osx 内核逻辑将大约 12.5%-25% 的 RAM 保留为非活动状态。

^2. 例如https://apple.stackexchange.com/questions/4288/what-does-it-mean-if-i-have-lots-of-inactive-memory-at-the-end-of-a-work-day

一旦所有内存都被使用(可用内存为 0),操作系统就会将非活动内存写入交换文件,以在活动内存中腾出更多空间。

更新日期:2012 年 3 月 17 日

以下是迄今为止建议的可以提供帮助的方法的总结:

清除命令

“用于通过冷磁盘缓冲区缓存近似初始启动条件以进行性能分析。它不会影响通过 malloc、vm_allocate 等分配的匿名内存”。

这对于防止 osx 换出磁盘缓存很有用(osx 实际上首先这样做是荒谬的),但缺点是磁盘缓存会被释放,这意味着如果磁盘缓存不打算被换出,那么最终只会得到一个冷磁盘缓冲区缓存,这可能会对性能产生负面影响。

FreeMemory 应用程序和/或修复磁盘权限以强制释放一些内存

没有帮助释放任何内存,只将几 GB 的内存内容从 RAM 移动到 HD。最后,当我尝试使用在释放内存时打开的应用程序时,这会导致大量交换,因为其许多虚拟机现在都在交换中。

使用以下方法加速交换分配动态分页包装器

为了加快交换使用速度,这似乎是一件好事,但在仍有非活动内存的情况下,这并没有首先解决 osx 交换的问题。

通过禁用来禁用交换动态分页器并重新启动

这将强制 osx 不使用交换,代价是当所有内存都用完时系统会挂起。这不是一个可行的选择...

使用以下方式禁用交换被黑客入侵的动态分页器

与上面禁用 dynamicpager 类似,博客文章评论中的一些摘录表明这不是一个可行的解决方案:“非活动内存像往常一样高”。“当您的系统内存不足时,整个操作系统都会挂起...”,“如果您消耗了 Mac 的全部内存,机器可能会挂起”

总而言之,我仍然不知道在仍有“非活动”内存时如何禁止 Mac OS X 使用交换。如果不可能,也许至少可以解释为什么 osx 更喜欢交换内存可能随时从记忆中释放

答案1

根据定义,非活动内存是准备被调出的内存,而将其调出可能涉及将其写入交换。这不是什么问题或需要优化的问题;事实上OS X 按设计运行

不幸的是,技术支持人员不是内核开发人员,Apple 知识库支持文章引用错误地声称非活动内存是程序未使用的内存。退出程序时,其所有常驻内存都会变为空闲;它不会停留在非活动状态。但是,第二个链接指向开发者网站如果完整阅读的话,描述内存管理如何工作是一个很好的资源。

关于 OS X 中“非活动内存”的含义,存在许多误解。与这些误解相反,并非所有非活动内存都是空的、未使用的、缓存的或可清除的。事实上,如果最近访问过活动内存,它也可以缓存或清除。许多非活动内存还包含不能简单丢弃的数据。如果丢弃这些数据,程序就会崩溃,因为丢弃的页面将包含有效数据(正如 OS X 开发人员所说的那样),并且程序希望存储在(虚拟)内存中的数据不会消失。

非活动内存包含与活动内存相同类型的数据。唯一的区别是 OS X 会注意到一些内存块在一段时间内没有被读取或写入。

OS X 将某些内存归类为非活动内存,而将其他区域归类为“活动内存”的原因与页面调出有关。当内存不足时,您将不得不调出一些数据。问题是,调出哪些数据?如果您调出程序马上又需要的数据,则会浪费时间且一事无成。因此,您需要调出程序不会马上再次需要使用的内存。

预测哪些页面将来可能不再需要是困难的,因为程序可以随心所欲地使用虚拟内存,而不告诉操作系统任何有关其计划的信息。但作为一种启发式方法,大多数程序在内存使用方面都是“固定的”;如果它们在一段时间内没有使用过某块内存,它们很可能会继续不使用该内存,并可能继续使用它们最近使用过的内存。

因此,当操作系统决定将一些数据移出页面时,它会采取交换最近未使用页面的策略。这就是 OS X 将程序占用的内存分为“活动”和“非活动”两堆的原因。以上发布的链接如果完整阅读,开发者网站会告诉你这个过程是如何发生的:

  • 当内存开始变低时,操作系统开始浏览活动内存页面,并在每个页面设置一个标志。
  • 如果程序读取或写入页面,则该标志将被清除。
  • 如果经过一段时间的延迟后,该标志还没有被清除,那么该页面就会被分类到“非活动”堆中。
  • 如果某个“非活动”页面被其程序访问,那么它将被放回到“活动”堆中。
  • 当内存耗尽时,“非活动”页面将被调出。

请注意,决定换出哪些内存的排序过程在所有现代操作系统中都是相似的。Linux 具有相同的两个活动和非活动页面列表,如理解Linux虚拟内存管理器。Windows 可能会使用一些略有不同的东西,具有两个以上的新近度类别;目前我找不到最近的、可靠的技术描述。维基百科页面讨论了更多实现,标题为“页面置换算法”。OS X 的唯一区别在于统计数据的显示方式:有人认为在活动监视器中分别显示活动和非活动数字是个好主意top。现在回想起来,这可能不是一个好主意(这在 OS X 10.9 中已经改变)。

设置和清除标志以及维护活动/非活动堆的过程确实需要一点处理器能力。因此,当有大量可用内存时,OS X 不会执行此操作。因此,您启动的第一个程序将显示为所有“活动”内存,直到可用内存开始不足。

因此,当您从一张白纸开始并打开越来越多的程序时,您可以期望在活动监视器中看到以下进展:

  • 首先,有很多“空闲”内存,很少处于非活动状态。这是因为内存标记器尚未开始运行。
  • 随着可用内存量的下降,OS X 将开始运行其内存标记程序,您将开始看到“非活动”内存量不断上升。每一位“非活动”内存以前都是“活动的”。
  • 当可用内存不足时,页面将从“非活动”堆中调出。内存标记器也将全力运行,将内存分类为活动内存和非活动内存。通常,在写入交换区时,您会看到很多“非活动”内存,这表明内存标记器正在执行其应执行的操作。

页面必须在被换出之前,它们会被归类为非活动状态。这就是 Apple Developer 网站上的引文“这些页面包含有效数据,但可能随时从内存中释放”的意思。这与活动页面相反,活动页面只有在降级为非活动状态后才会被释放。释放页面有多种方式;如果页面是从文件映射的并且尚未修改,则可以立即删除并根据需要重新读取。如果它是以前被换出的内存,并且自从换入以来没有修改过,情况也是如此。程序还可以明确分配缓存和可清除内存,以存储可以忘记并根据需要重新创建的数据(但程序分配缓存的原因是重新创建该数据需要大量时间。)但许多非活动内存是程序已将有效数据写入的内存,而将这些数据换出需要写入交换。

因此,查看活动监视器中的“非活动”内存量,并看到在计算机写入交换的同时有大量非活动内存,只能告诉您系统正在按设计运行。

不活跃内存和文件缓存之间也存在混淆。我不确定为什么会有这种混淆,因为活动监视器已经将它们列在不同的标题下。缓存是用于存储最近从文件系统读取或写入的数据的内存,以防需要再次访问它们。当内存不足时,OS X 往往会首先清除缓存。如果你有交换抖动,并且活动监视器显示一大堆缓存(不是不活跃的),那么会是个问题。但不活跃的记忆又是另一回事。

如果有疑问,请忽略“非活动”和“活动”之间的区别。将它们视为“程序使用的内存”的集合,并将两个数字相加。这是其他所有操作系统在告诉您内存使用情况时所做的。

对于 OS X 10.9 的注意事项:Mavericks 引入了“内存压缩”,这或多或少是另一层交换。活动页面现在被归类为非活动页面,然后被压缩(根据您使用的工具,可能会显示为内核内存),然后随着内存使用量的增加写入交换。Mavericks 还停止在活动监视器中显示活动和非活动的不同数字,因为事实证明这没什么用,尤其是考虑到围绕它的误解。

答案2

目前还没有简单的方法来调整 macos X 的 swappiness (或称其为 swappiness) 行为。不过有一些可用的技巧 (需要开发者帐户和 SDK):

http://cestdelamerde.com/archives/22-Killing-Mac-OS-X-Swapping-How-To-Disable-dynamic_pager.html

http://dropsafe.crypticide.com/article/3848

祝你好运!

后记。我猜你可能想读一下这个答案(也是我写的),以便对 MacOSX 中的活动、非活动和其他内存有一个更全面的了解:OS X 中的有线内存与主动内存

答案3

虽然这不是一个永久的解决方案,但至少它可以帮助回收一些不活动的内存,从而有可能避免可怕的交换:http://itunes.apple.com/nz/app/freememory/id460931672?mt=12

该工具免费且易于使用。启动后,在系统工具栏/菜单中选择“释放内存”选项。

与 ActivityMonitor 内存显示不同,它仅显示可用内存,这似乎可以更好地指示交换是否正在进行。

答案4

我敢打赌这个问题没有正确答案。这和当你让 Mac 进入睡眠状态时内存仍然处于活动状态是一样的,它只会随着你每次睡眠而不断增长。

从“乐趣”(也就是昂贵)方面来说,您可以升级内存或用 SSD 替换 HDD,因此更换不会对性能造成影响。我选择了第一个选项,因为 Corsair 内存现在价格合理。

16GB 内存

相关内容