Windows 怎么能这么快地将完整的 RAM 转储到休眠文件中?

cod*_*der 66 memory windows hibernate

我正在阅读一篇解释 Microsoft Windows 中的休眠程序的文章。我从中得出的主要观点是

  1. Windows 将整个 RAM(可能在处理之后)转储到hiberfil.sys文件中。
  2. 在启动过程中,读取休眠文件,并将内容加载到 RAM 中。

我的问题是,当我通常复制大小为 1 GB 的文件时,大约需要2 分钟才能完成。

但是,当 Windows 正在写入休眠文件时(在休眠过程中),整个过程可能需要 10-15 秒。 为什么写入速度会有如此大的差异?

我的 RAM 大小是 4 GB。(我不是在谈论快速启动技术。)

基准:

  1. 将 1 GB 文件从磁盘 1 复制到磁盘 2(外部):2.3 分钟。
  2. 休眠系统:15 秒。

Mok*_*bai 46

这可能是一个三重的答案。

可能在这里起作用的一件事是 Windows 中新的混合关机,它有效地关闭了您的应用程序,将您注销,然后继续休眠操作系统的核心。已经保存了这些数据意味着它不需要潜在地“重新休眠”它。

第二件事是休眠不需要保存已调出到交换文件或未使用的内存页面(这将是积极填充交换文件并将数据保留在内存中的一个原因) .

第三是休眠文件数据也被压缩。结合我的第二点,如果您只有一小部分数据要导出,其中包含高度可压缩的数据(可执行文件通常可以很好地压缩),那么输出到休眠文件的数据量可能比工作集小得多数据的。请注意,如评论中所述,文件缓存和其他不必要的缓冲区数据可以很容易地被丢弃而不会产生不良影响,以减少要转储到休眠文件中的数据量。

此外,当前的硬盘驱动器速度非常快。使用具有 100 MB/s 数量级持续写入的磁盘,您将能够在一分钟内写出(未压缩)4 GB 的 RAM。由于休眠可以作为挂起所有用户进程之后和挂起 CPU 之前的最后一件事来完成,因此操作系统通常具有磁盘的完整写入速度。这是您的简单基准测试所没有的一件事,从磁盘复制到磁盘可能比简单地将 RAM 写入磁盘要慢。

结合这些内容,写入休眠文件的数据量可能非常小,可能只有 1 GB 的数量级,并且可能会在 10 秒内写入一个大的连续块。

  • 或者,更清楚地说:您的 RAM 可能未满。在休眠时刷新缓冲区并丢弃缓存。只有*实际由应用程序使用*的内存必须写入磁盘。混合关机通过注销用户来减少正在使用的内存量。 (37认同)
  • @user2284570:那是因为最坏的情况是 1:1 压缩。Windows 必须确保 hyberfil.sys 中有足够的(保留)空间用于任何可能的内存配置 - 即使它只需要十分之一的 RAM 大小用于特定的休眠。此外,RAM 使用的相当一部分是加载到内存中的文件(可执行文件、资源...),但仍从 HDD 映射,您确实可以节省大量写入。让程序在 RAM 中生成 4 GiB 的加密随机数据,并且休眠所需的时间要长得多——即使如此,其中一些可能已经在交换中。 (5认同)
  • @user2284570 来自我在该答案中链接的文档 *“Windows 通过将内存内容复制到磁盘来支持休眠。系统会在将内存内容保存在磁盘上之前对其进行压缩,从而将所需的磁盘空间减少到小于物理总量系统内存。"* (3认同)
  • @ user2284570:文件很大,以确保磁盘上有空间来存储所有内存。并非所有这些空间实际上都用于休眠。有时文件会是(比如)7% 的压缩内存内容,93% 的垃圾。 (3认同)
  • 不脏的页面是“调出到交换文件”的更一般的声明,这将包括可执行文件。(由于可执行文件在磁盘上有些碎片,这可能会减慢唤醒速度。)此外,即使干净的文件缓冲区不是内存映射文件的一部分,也可能会被删除。 (2认同)
  • 根据我相信我在这里读到的内容,Windows 实际上也不会将也存储在磁盘上的内存中的文件写入休眠文件或页面文件。在内存压力下,它只是从内存中删除文件,然后在需要时将它们从磁盘中带回来。本质上,每个文件都充当其自己的分页文件。 (2认同)
  • @user2284570 这与我所说的没有任何关系:) (2认同)

Dam*_*mon 32

首先,需要节省的 RAM 量非常小。事实上,只需要刷新映射的脏页集(“延迟回写”),以及所有已写入和重定位的可执行代码的私有页面都需要写入。

  • 可执行文件的 .text 段始终由文件映射支持。至少对于某些DLL也是如此(但不是全部,取决于它们是否需要重新定位)。
  • 同样由文件映射支持的内存可以被丢弃(假设它不是 CoW 或 RW并且是脏的)。
  • 延迟写回仍然会发生,但除此之外,缓存可以被丢弃。
  • 已分配但未写入的内存(通常是应用程序数据的大部分!)由零页支持,可以丢弃。
  • 那是在“待机”状态的内存页的较大部分(实际每进程驻留在Windows工作组是惊人地小,区区16MB)将已在某些时候被复制到页面文件在后台可以被丢弃.
  • 由某些设备(例如显卡)映射的内存区域可能(可能)不需要保存。用户有时会惊讶于他们将 8GiB 或 16GiB 插入计算机,而 1GiB 或 2GiB 只是无缘无故地“消失”了。主要的图形 API 要求应用程序能够“在某些条件下”使缓冲区内容变得无效(没有确切说明这意味着什么)。因此,期望由图形驱动程序固定的内存也被丢弃并不是没有道理的。毕竟,无论如何,屏幕都会变暗。

其次,与复制文件相反,从驱动器的角度来看,转储需要保存到磁盘的一组 RAM 页面是单个连续的连续写入。Win32 API 甚至为此操作公开了一个用户级函数。Gather write 由硬件直接支持,其工作速度与磁盘物理上能够接受数据的速度一样快(控制器将通过 DMA 直接拉取数据)。
这有很多前提条件(例如对齐、块大小、固定),并且它不能很好地与缓存一起使用,并且没有“懒惰回写”之类的东西(这是正常操作下非常理想的优化)。
这就是为什么不是每次写一直这样工作。然而,当系统保存休眠文件时,所有先决条件都会自动满足(所有数据都是页面对齐、页面大小和固定的)并且缓存变得无关紧要,因为计算机马上就要关闭了。

第三,单次连续写入对于旋转磁盘和固态磁盘都非常有利

交换文件和休眠文件通常是磁盘上最早创建和保留的一些文件。它们通常有一个,最多两个片段。因此,除非扇区损坏并且磁盘必须重新分配物理扇区,否则逻辑顺序写入将转换为旋转磁盘上的物理顺序写入。

当写入大量连续的连续数据时,不需要对磁盘进行读-修改-写操作。这个问题在可以写入非常小的单个扇区的旋转硬盘上不太明显(如果您不写入单个字节,缓存通常会阻止,则设备不需要获取原始内容并写回修改后的版本。) .
然而,这在 SSD 上非常明显,其中每次写入意味着例如 512kB 块(这是一个通常的数字,但它可能更大)必须由控制器读取和修改,然后写回不同的堵塞。虽然您原则上可以写入(但不能覆盖) 闪存盘上的较小单元,您只能擦除大块,这就是硬件的工作原理。这就是 SSD 在大量顺序写入时表现如此出色的原因。

  • @PeterMortensen:不,我的意思是 _gather_ 写(而不是分散读)。这意味着在_收集_来自多个位置的数据时写入单个文件。您提供一个结构数组,每个结构都包含一个起始地址和一个长度(具有严格的对齐要求)。操作系统将这些传递给控制器​​,剩下的交给硬件。 (3认同)

小智 10

它不会在休眠时转储整个 RAM。

它已经在磁盘上复制了很大一部分 RAM。这不仅可以让休眠快速发生,而且还可以让新程序快速使用内存(以便它们可以快速启动)。

因此,它只需要写入 4GB 的一小部分,并且可以在 10-15 秒内完成。

来自微软

当 RAM 供不应求时(例如,提交的字节数大于已安装的 RAM),操作系统将尝试通过将未处于活动状态的虚拟内存页面复制到页面文件来保留一部分已安装的 RAM 以供立即使用. 因此,此计数器不会达到零,并且不一定能很好地指示您的系统是否缺少 RAM。


Wil*_*ilf 0

这可能是因为RAM的输入/输出速度比硬盘快得多,因此RAM可以像硬盘读取数据一样快地输出其中的内容。

复制文件时,您还受到各种因素的限制 - 磁盘的速度,如果必须在同一磁盘上读入和读出,则需要更长的时间,连接的速度有限(如果是外部驱动器),请检查它没有覆盖任何东西等

  • 但操作系统仍然需要将 4GB RAM 数据写入磁盘,这受到 I/O 瓶颈的控制 (9认同)

归档时间:

查看次数:

14373 次

最近记录:

10 年,6 月 前