![什么是“已提交内存”、“缓存”、“分页”、“非分页池”以及它们与“正在使用的内存”有何不同](https://linux22.com/image/1584073/%E4%BB%80%E4%B9%88%E6%98%AF%E2%80%9C%E5%B7%B2%E6%8F%90%E4%BA%A4%E5%86%85%E5%AD%98%E2%80%9D%E3%80%81%E2%80%9C%E7%BC%93%E5%AD%98%E2%80%9D%E3%80%81%E2%80%9C%E5%88%86%E9%A1%B5%E2%80%9D%E3%80%81%E2%80%9C%E9%9D%9E%E5%88%86%E9%A1%B5%E6%B1%A0%E2%80%9D%E4%BB%A5%E5%8F%8A%E5%AE%83%E4%BB%AC%E4%B8%8E%E2%80%9C%E6%AD%A3%E5%9C%A8%E4%BD%BF%E7%94%A8%E7%9A%84%E5%86%85%E5%AD%98%E2%80%9D%E6%9C%89%E4%BD%95%E4%B8%8D%E5%90%8C.png)
答案1
问题 1 的答案:
- 正在使用指实际使用的物理内存量。
- 这已提交记忆中的第二个数字指的是提交限制,即物理内存量+页面文件的大小。
- 这提交记忆中的第一个数字指的是应用程序请求使用多少内存。
- 当应用程序首次请求使用一定量的内存时,Windows 会确保该内存可以放在某个位置,无论是页面文件还是内存中。这并不意味着大量内存占用了实际物理内存或页面文件空间。这只是意味着 Windows 在总提交限制中保留了这部分空间,以备不时之需。大多数请求的内存都被使用,但并非全部。
- 已缓存指用于加速文件系统访问的物理内存量。在客户端操作系统上,最多 10% 的内存用于缓冲写入(“脏页阈值”)。
- 分页池是可以从物理内存溢出到慢速页面文件的内核和设备驱动程序内存量(来源)。
- 非分页池是必须保留在物理内存中的内核和设备驱动程序内存量。此类内存不能卸载到磁盘上。
问题 2 的答案:
简单来说,在 Windows 上,“内存”可以由物理 RAM 或页面文件(在磁盘上)支持。页面文件用于多种用途,包括为不经常访问的程序释放物理 RAM。它比物理 RAM 慢几个数量级,因为它由磁盘支持,无论是否旋转。
如果您的系统没有足够的内存,您正在使用的应用程序可能会溢出到磁盘并导致系统速度急剧下降。
从答案 1 中可以看出,仅从这些数字来判断是否有足够的内存并不容易。
我建议使用以下方法来确定您是否有足够的内存:
- 启动资源监视器(Win+R并输入
perfmon /res
) - 像平常一样使用您的笔记本电脑。
- 当您注意到速度变慢时,请返回资源监视器并查看右侧的内存图。硬故障大致是指它必须访问页面文件以进行内存访问的次数。硬故障的数量应接近 0。如果不是,则说明您没有足够的 RAM 来执行任何操作。
您有几种补救措施:
- 在系统变慢之前关闭未使用的应用程序或选项卡。
- 如果可能的话,升级 RAM。
答案2
没有按照您要求的顺序进行操作...
(注:这仍在进行中。我可能会在接下来的几天内对其进行调整和编辑。我会添加屏幕截图。)
(请注意第二点:我意识到这篇文章很长。这是我能写得最短的,至少能回答大多数在较短的答案中经常出现的问题。为了比较,Windows 内部原理大约有 200 页,足以写成一本不错的书。如果你真的想学习这些内容,还有另一本书(我推荐)叫做是什么让它成为页面?更详细。它只有 600 多页。正如我上面提到的,我可能会在接下来的几天内编辑它,但不要指望它会变短!)
正在使用
正在使用是与可在不发生页面错误的情况下进行访问的虚拟页面相对应的物理内存 (RAM) 量。
注意:这不是在不发生页面错误的情况下可以访问的虚拟内存量!这是一个更大的数字。许多不同的虚拟页面可以映射到同一个物理页面。
背景:每个虚拟页面可以是“有效的”,这意味着它占用物理内存,并且其页表条目已设置“有效”位。或者有效位可以是清除的,在这种情况下引用虚拟页面将导致页面错误。然后操作系统必须解决该错误。然后该页面被称为已“错误地”进入 RAM。这通常被认为是“从磁盘读取页面”,但事实往往并非如此(稍后详细介绍)。您会听到的另一个用于表示有效页面的术语是“驻留”。
主要贡献者正在使用是包含工作集进程和操作系统,加上非分页池(通常相当小,几百 MB 左右 - 稍后我会详细介绍)。进程的工作集只是该进程当前“驻留”的物理页面的列表。每个进程都有自己的工作集列表。
注意:物理 RAM 页可以同时位于多个进程的工作集中。这意味着,将所有进程的工作集大小相加将得到一个大于它们实际使用的 RAM 量的数字。正在使用不过,总计正确地解释了共享页面;也就是说,它不会对它们进行双重或多重计算。
注意:术语正在使用可能会产生误导,因为待机和已修改列表中的 RAM 页面也可以说是“正在使用”,即使它们无法在没有页面错误的情况下被访问并且它们不在任何工作集中。这两个列表将在稍后进一步解释。
注意:本次讨论中会大量提及进程及其工作集。Windows 操作系统的内核模式代码和数据也位于虚拟内存中,其中大部分是可分页的。也就是说,它不必一直停留在 RAM 中,就像应用程序代码和数据一样。虽然它本身不是进程(尽管是所谓的“系统”进程),但有一个工作集来跟踪对操作系统“有效”的页面——或者更准确地说,对内核地址空间有效。事实上,从 Windows 7 及更高版本开始,系统工作集被分为四个工作集(用于各种类型的可分页代码和数据),主要是出于性能原因。我谈论的有关工作集的几乎所有内容都适用于操作系统的工作集以及进程的工作集,但我不会每次提到进程工作集时都添加“或操作系统工作集之一”。
可用的
你没有问这个,但它很重要。可用的是可以分配给新用途的所有 RAM(例如,分配给之前使用它的进程以外的进程,甚至分配给同一进程内的新虚拟页面),而无需将其从工作集中移除,也不必将其内容保存在某处。(因为如果内容很重要,它们已经保存在某处)。
可用的不会出现在当前任务管理器的“性能”选项卡的“内存”窗格中。它显示在“资源监视器”的“内存”选项卡中。它是待机、可用和零页列表的总和。有关这些的详细信息即将发布。
已缓存
这已缓存任务管理器“性能”选项卡上的计数器是以下三种 RAM 使用情况的总和。它是 RAM 的计数,而不是虚拟内存的计数。
已缓存第一部分:待机页面列表(包括超级获取)
这在“资源监视器”的“内存”选项卡上可见。在 Windows Vista 之前,它仅用作“页面缓存”:从工作集中删除的 RAM 页面(此后引用它们将导致页面错误)首先被放入备用页面列表。从那里可以将它们重新分配给其他用途(“重新利用”)。但是,如果原始进程在此之前引用了 SPL 上的页面,则可以将该页面恢复到其原始工作集(即,可以“使其有效”),而无需从磁盘读取它。因此,SPL 形成了一个系统范围的先进先出页面缓存,这些页面可能很快会再次需要。(与工作集相反,工作集是按每个进程的;页面是按最近最少使用的原则从工作集中删除的,而不是按 FIFO 删除的。)
所有这些仍然适用。但从 Vista 及更高版本开始,SPL 上的某些页面可能重新利用供使用超级获取。SuperFetch 是一种主动的只读文件缓存机制,它保留经常访问的文件的历史记录,并在实际请求这些文件之前将其读入 RAM 以加快速度。
SuperFetch 的巧妙之处在于,SuperFetch 使用的页面不会从待机页面列表中删除,因此仍然可以在很短的时间内重新利用,就像 SPL 上的其他任何内容一样。而且它们仍然算作已缓存。和作为...的一部分可用的。因此 SuperFetch 不会真正“使用”任何 RAM!或者至少,它不会占用“可用的“,也不会有助于”正在使用“。
在操作系统磁盘为 SSD 的系统上,默认情况下 SuperFetch 处于禁用状态。备用列表仍按此处所述用作页面缓存。
待机页面列表是 RAM 的一部分,报告为可用的,这意味着它的任何页面都可以随时重新用于其他用途 - 即使是 SuperFetch 正在使用的页面。不是部分正在使用,即使它正在被使用。SuperFetch 肯定在使用它!每次软页面错误被解析到 SPL 时,它也会被使用。我在这里要说的是,声称正在使用“正在使用的” RAM 数量最多只能算是一种误导。微软应该为正在使用。
已缓存第 2 部分:已修改页面列表
从 Windows 8 及更高版本开始,已缓存计数器还包括位于已修改页面列表。(MPL 已经存在很久了;唯一的新变化就是将其算作已缓存)与 SPL 一样,MPL 的大小可以在资源监视器的“内存”选项卡上看到,尽管它通常应该很小或为零。
MPL 与 SPL 类似,不同之处在于它用于驻留期间内容被修改的页面。(这由 CPU 的 MMU 记录。)当从工作集中删除时,这些页面将移至 MPL 而不是 SPL。“系统”进程中的“修改页面写入器”线程会定期唤醒,将这些页面的内容复制到各自的后备存储器(页面文件或文件后备页面的各自文件),然后将它们移至备用页面列表,此时它们将成为可用的并且他们受到的待遇就像他们一开始就被列入 SPL 一样。他们不是可用的而在 MPL 上,因为在其内容被保存到某处之前,它们不能被重新用于其他用途。
MPL 不计入正在使用任何一个。
请注意,如果您(愚蠢地、无视好建议)禁用了页面文件,系统将永远无法写出页面文件支持的已修改页面。通常的症状是 MPL 过大,这会导致可用 RAM 不足,从而导致“页面抖动”,即操作系统将页面复制到 RAM 和从 RAM 复制出的时间比执行您想要执行的工作的时间还多。
Windows 10 的“压缩内存”功能在某种程度上改变了“写入页面文件”部分;我不会在这里讨论这个,因为它不会影响我们正在讨论的计数器。
已缓存第 3 部分:文件系统缓存
- 更新:在 Windows 10 的许多版本中,或者可能早在 Windows 8 中,这不再是任务管理器的一部分已缓存计数器。但它仍然存在,我提到的 PerfMon 计数器仍然存在并且处于活动状态。文件系统缓存的驻留大小仍然包含在正在使用。我必须做一些测试才能确切地知道这是什么时候改变的。
或者至少是文件系统缓存的“常驻”部分。再次强调,“常驻”意味着它是较大虚拟分配的 RAM 中、工作集中的部分。
嘿,我们不是已经讨论过缓存了吗?“SuperFetch”?是的,但是这与 SuperFetch 不是相同的缓存。与 SuperFetch 不同,文件系统缓存是一种反应式缓存(从不预测 - 即它永远不会缓存任何东西直到它实际被使用,然后它被缓存以供将来快速使用(在同一个操作系统实例内)。
文件缓存在支持非扇区对齐边界上的文件访问方面也发挥着重要作用。如果您使用“无缓存”选项打开文件,则所有读取和写入都必须是驱动器扇区大小的倍数,并且必须从扇区边界开始。文件缓存允许您一次只读取和写入一个字节(至少就您的 API 调用而言)。
在早期版本的 Windows 中,文件缓存的常驻部分是系统工作集的一部分,其对系统工作集的贡献可以在 PerfMon 计数器中找到Memory | System Cache Resident Bytes
。从 Windows 7 及更高版本开始,系统工作集已被拆分为四个单独的工作集,文件缓存占据其中一个,并且同一个计数器仍然反映其常驻大小。无论哪种方式,文件系统缓存的常驻部分都包含在“正在使用”中(因为它是一个工作集)。
- 注意:任务管理器的“缓存”计数器与 CPU 的内部缓存(L1、L2 等)没有任何关系。这些缓存当然存在,但 Windows 并不管理它们,它们也不会反映在任何操作系统的内存管理计数器中 - 不是“总计”,不是“使用中”,当然也不是“缓存”。
非分页池和分页池
这分页和非分页计数器给出内核地址空间的两个区域(称为“内存池”)的虚拟大小。这两个区域都用于相当小的短期内存分配(通常每个都远低于 1 MB),这些内存是 Windows 内核模式代码的各个组件(包括设备驱动程序)所需要的。内核模式代码使用这些内存的方式与应用程序使用“堆”的方式非常相似。(Windows 将它们称为池而不是堆的原因是历史原因。)
其中一个泳池是非分页这意味着它始终保存在 RAM 中。因此,对于这个,任务管理器指示的大小是物理(RAM)大小以及虚拟大小。非分页池由可能在无法处理页面错误的上下文中执行的组件使用,例如设备驱动程序的中断服务例程、DPC 例程和其他必须在 IRQL DISPATCH_LEVEL 或更高级别运行的例程。我在另一个答案中解释了 IRQL。
另一个池子叫分页通过任务管理器,实际上应该称为“页面有能力的“。就像进程使用的普通虚拟内存一样,它不是一定分页出来,只是其中的一部分能与所有其他可分页区域一样,其页面将根据需要“故障进入”RAM - 即在不在 RAM 中时被引用 - 并且如果物理内存不足并且必须解决新的页面错误,则可能稍后“分页出”。
任务管理器显示的可分页池大小是虚拟大小。其中的一个子集将是“有效的”,即 RAM 中的部分(即物理大小)。任务管理器不会报告分页池的 RAM 中(分页)部分的大小,但可以在 SysInternals 工具进程资源管理器(查看 | 系统信息)或 PerfMon 计数器中看到Memory | Pool Paged Resident Bytes
。
所有“非分页”池以及分页池的“分页”或“常驻”部分都属于“正在使用”的一部分。
有关内核内存池的更多信息,请参阅内核接口的文档ExAllocatePool
。
警告:非分页不是页面调入子集分页!这些是单独的虚拟分配。因此,完全有可能,例如,非分页池显示的大小大于分页池 - 但并不常见。
注意:这些绝不是内核虚拟地址空间的总量。
坚定的
这坚定的计数器指的是一种特定类型的虚拟内存。要真正解释这一点,我必须解释其他类型。
虚拟地址空间的每一页都可以处于以下五种状态之一:未使用,不可分页,已映射,保留和已提交。
“不可分页”、“已提交”和“映射”虚拟地址空间对应于虚拟记忆并且可以成功访问(读取或写入),但可能在此过程中出现页面错误;“未使用”和“保留”则无法访问。
(您有时会看到错误消息 - “0x(某个地址)处的指令引用了 0x(某个地址)处的内存,无法读取(或“写入”)该内存?如果系统上的代码尝试访问“未使用”或“保留”的地址空间,就会发生这种情况。或者,如果尝试写入只读页面,或从用户模式访问受内核保护的虚拟地址。注意:报告的地址是虚拟的,而不是物理的,并且该消息并不意味着您的 RAM 有问题。这是程序中的一个错误。)
“不可分页”虚拟内存始终是物理“驻留”的,并且几乎完全属于 Windows 内核模式代码。它是“正在使用”的一部分。非分页前面已经讨论过了,内存池是不可分页虚拟内存的一个例子。
注意:尽管不可分页虚拟内存始终驻留,但我们仍将其视为“虚拟”,因为我们仍通过虚拟地址引用它。它还具有虚拟内存的所有其他属性,除了它始终是“有效的”,因此访问时永远不会产生页面错误。
“映射”虚拟地址空间可从磁盘调页。它的“后备存储”——如果不能同时将部分内容保存在 RAM 中,则将其保存在后备存储中的别称——是创建每个映射区域时提供的文件。(此处的相关 API 是CreateFileMapping
和MapViewOfFile
。)映射区域的内容实际上从这些文件中开始;它在被访问时被读入 RAM(“按需调页”)。
顺便说一句,映射内存非常常见 - 所有可执行代码都位于映射区域中。与传统的读/写访问不同,映射内存也常用于访问大文件。
映射区域可跨进程共享。如果映射设置为读/写访问(通常不会对代码文件进行设置!),则对映射 vas 的修改将写回到相应的映射文件。
但是,可以创建一个“页面文件支持的映射区域”,该区域可以像任何其他映射区域一样在进程之间共享,但是一旦所有进程取消映射,对该区域的更改将不会在任何地方保留。
“已提交”虚拟地址空间也可从磁盘分页。这与“已映射”的区别在于,“已提交”虚拟地址空间的后备存储(如果需要)是页面文件(如果您有的话,您肯定应该有)。
“已提交”和“已映射”一样,都是按需分页,但第一次访问已提交内存页面时,不会从磁盘读取 - 因为与映射内存不同,没有地方读取初始内容从。只需将新的物理页面分配给进程(从先前的“可用”RAM,通常是零页列表)并在进程工作集中使其有效。因此,已提交内存的页面在第一次被引用之前不会占用任何存储空间。
由于已提交内存是可分页的(即使您没有页面文件,但您确实应该有一个),因此并非所有页面都可能同时位于 RAM 中 - “驻留”。像往常一样,操作系统会尝试将最近访问的 vas 页面保留在 RAM 中;如果可用 RAM 稀缺,则操作系统将“分页”其他页面,将它们从工作集中移除并放在 SPL 或 MPL 上。在后一种情况下,它们很快就会被写入其后备存储器。
所有进程加上操作系统内核的“已提交”的总大小(即分页文件支持的,或者如果您有分页文件的话,肯定应该有),是单词下方的第一个数字坚定的。
它还包括其他几个贡献:主要是非分页池和分页池,以及任何以写时复制方式映射的映射区域。这个数字通常被称为承担责任。
考虑提交费用的一种方法是:如果你有一个页面文件(你应该有),并且全部除映射内存之外的可分页内存内容(已提交、分页池等)必须从 RAM 中分页 - 这就是所需的页面文件空间量。
单词下方的第二个数字坚定的是“提交限制”。这是 RAM 的大小加上页面文件的当前总大小。提交费用不允许大于该值。如果某个进程尝试提交超过提交限制大小的虚拟内存,那么如果可能,Windows 将扩大页面文件以腾出空间(您将看到“内存不足”弹出窗口)。如果无法扩大页面文件,则消息将显示“内存不足”,并且执行此操作的进程将崩溃。
提交费用的常驻子集是“正在使用”的一部分。请注意,即使您没有页面文件(如果没有,那您有什么问题?),这也不一定与提交费用相同。首先,如果您提交了虚拟内存,但并未访问所有内存,则您未访问的部分将永远不会占用任何存储空间。提交的内存也可能从工作集中删除并放入已修改页面列表中。通常,只有提交内存的子集会占用 RAM。
任务管理器无法确定 RAM 中已分配内存的子集。不过,SysInternals 工具“RAMmap”可以显示这一点。
总结
可用的+正在使用+修改的加起来等于操作系统可用的总 RAM。
操作系统可用的总 RAM 加上“硬件保留”RAM 应该等于安装的总 RAM 量。
可用的等于待机页面列表,再加上空闲页面列表,再加上零页列表
自由的 如资源监视器的“内存”选项卡所示是零页列表与空闲页列表的总和。
(我故意省略了对零页列表的更多讨论,因为它对于所询问的计数器来说并不重要。)
已缓存=待机页面列表(其中一些由 SuperFetch 使用),加上(对于 Windows 8 及更高版本)已修改页面列表,加上(对于早期版本的 Windows 尚未准确确定)系统文件缓存的页入或常驻部分。
注意:由于待机页面列表是“可用”和“缓存”的一部分,因此完全可以将“可用”和“缓存”相加,并得到大于 RAM 总量的总数!这些数字根本不应该加在一起。
资源监视器的“内存”选项卡将可用内存和零内存的总和显示为一个数字,标记为“可用”。性能监视器可以单独显示这些大小。
我的 RAM 够用吗?
“据我所知,内核以复杂的方式操作内存管理,所以我是否可以得出结论,如果我的笔记本电脑内存中有可用内存,那么我的内存就足够了?”
“我的 RAM 是否足够?”的最佳衡量标准通常是您的硬页面错误率。硬页面错误是需要从磁盘读取的页面错误。您可以在资源监视器右栏的图表(“概览”和“内存”选项卡)或“内存”选项卡上按进程查看此信息。PerfMon 计数器Memory | Page Reads/sec
也会显示此信息。
总体故障率是硬故障率的超集,远没有那么有趣。它包括“软页面错误”,它不涉及磁盘读取,因此花费的时间要少得多。(很难说它们需要多少时间,但我估计最多需要几百条指令。)这些包括解决备用和修改页面列表的故障、已经驻留在一个或多个其他进程中的共享页面的故障,以及“需求零”故障,这些故障发生在第一次引用私有页面时。如果您看到每秒数千个页面错误,请不要感到惊讶。正是从磁盘读取页面极大地减慢了速度(即使您的磁盘是 SSD)。
但是“可用”或“免费”又如何呢?
许多人担心“可用”内存或“空闲”内存的数量。首先,对于 Windows 系统来说,如果很长时间没有退出很多进程,则显示没有或几乎没有空闲内存,这是很常见的。这是预料之中的,因为通常将内存返回到“空闲”状态的唯一事件是进程退出时;然后,对其“已提交”内存有效的物理页面将移至“空闲”列表。
“可用”包括备用列表,并且与“空闲”一样可以分配给新用途,因此,如果您有足够的“可用”空间,就不必担心其中没有太多“空闲”空间。
即使对于“可用”,拥有充足的可用的内存用于支持快速启动新程序或已运行程序中的新行为。此时,您会看到大量硬页面错误 - 这是完全正常的,事实上,是不可避免的。如果您的工作负载不经常发生这种情况,那么您的系统可以接受较低的可用 RAM 百分比。
我再说一遍:SSD 导致的硬页面错误比旋转磁盘更快。如果是 M.2 PCIe SSD,速度会更快。但仍然比软错误慢得多。
还有一件事:您经常会听到这样的说法:“RAM 永远不够用”。好吧,确实(除非出现某些特殊情况),为系统添加 RAM 永远不会导致性能下降。问题。但是你肯定可以花太多钱在 RAM 上。存在一个收益递减点,超过这个点,添加更多 RAM 不会明显加快系统速度。这个点在哪里取决于您的工作量和硬件的各个方面(特别是您使用的是 SSD 还是旋转磁盘)。正如我上面所言,删除页面文件不会消除对磁盘的分页,因为映射文件仍然存在,并且仍然通过分页进行读写。因此,删除页面文件(您无论如何都不应该这样做)并不意味着您可以不再担心磁盘的速度。
答案3
问题 1:
已提交内存、缓存、分页、非分页池到底是什么,以及它们与正在使用的内存有何不同。
已提交的内存: 已分配内存是所有已分配使用内存的形式。这包括物理内存和虚拟内存(分页)。已承诺内存与可用内存
缓存内存:内存通常内置于 CPU 中。这种内存的访问速度更快,因为它距离使用它的处理器最近。
分页内存: 分页内存是虚拟内存,即没有物理连接到系统。当系统确定需要的内存超过可用内存时,它将创建虚拟内存,这实际上只是硬盘上的存储空间。这种类型的内存速度要慢得多,因为它依赖于硬盘的读/写速度。
未分页: 与分页内存正好相反。这意味着它是不包括分页内存量的总内存量。
问题2:
据我所知,内核以复杂的方式操作内存管理,所以我是否可以得出结论:如果我的笔记本电脑内存中有可用内存,那么我的内存就足够了?
一般来说,确保有足够的物理内存来执行最耗内存的任务是明智之举。如上所述,分页内存在技术上可以完成任务,但与物理内存相比速度会慢得多。我建议您监控内存水平,打开并运行您认为实际会运行的最耗内存的设置,然后查看有多少内存被使用。