我需要评论这个问题,特别是“页面表”和“页面文件”之间的混淆。这不是一个答案,但它不能容纳在注释中。
“页面表”确实与页面文件有很大不同。具有n MB的RAM用于页表并不意味着您正在使用n MB的页文件空间。而且,尽管某些页表条目(页表所组成的PTE)确实引用了页文件的内容,但并非全部。
页表是用于由CPU的MMU进行内存结构的地址转换从虚拟地址(再次,没有页面文件)为物理地址,并通过操作系统来跟踪虚拟地址空间,并帮助解决页面错误的。页表由页表项(PTE)组成。每个PTE占用8个字节,并定义4K字节的虚拟地址空间-即一个虚拟页面。大约每个虚拟地址空间的非空闲页都有一个PTE。
顺便说一句,尽管页面文件可以同时经历内部和内部碎片(前者通常不是什么大问题;后者可以通过使其变成所需大小的四倍来改善),但是页表却不能。它们已经总是零散了,一点也没有关系。
每个PTE都有一个“有效”位。对于“有效”页面(也称为“驻留”页面),PTE包含与该PTE关联的虚拟页面编号相对应的物理页面编号;它由MMU直接使用。
对于“无效”页面,MMU会引发页面错误,然后PTE具有许多可能的格式和解释。
注意:以上所有内容适用于在x86 / x64上启用分页的任何操作系统。以下内容主要针对Windows,但是许多概念适用于其他OS,但实现细节有所不同。
对于页面缓存中的页面,PTE仍包含物理页面号。对于已从RAM中丢失并写入页面文件的页面,PTE确实包含页面文件编号和页面内容写入页面文件内的偏移量。其他可能的PTE内容是对虚拟地址描述符的引用,对“原型PTE”的引用,对需求零页的引用等,我将不介绍它们。只需说一些PTE引用页面文件中的位置就足够了。
我提到所有这些主要是为了表明页面文件和页面表虽然相关,但绝对不是同一回事。
页表被组织成树状结构。每个进程都有一个不同的树或页表集合-这就是允许每个进程定义自己的虚拟地址空间实例的原因。树根的页表必须始终位于RAM中。其他可分页;它们甚至不存在,它们对应于未定义或可用的虚拟地址空间的大区域(至少2 MB)。
在树的“叶子”处的表中的页面表条目对应于虚拟地址空间的页面。较高级别的表中的PTE-靠近根(以及根本身)的PTE告诉下一个较低级别的表在哪里(如果它们根本存在)。
RAMmap显示的数字是所有进程以及OS的所有驻留(RAM中)页表所占用的物理内存(RAM)。
在这里重要的是,OQ中的系统有2.5 GB的RAM与页表捆绑在一起。这意味着至少定义了2.5 GB的页表。由于页表本身是可分页的,因此虚拟大小可能比物理大小大得多,这是RAMmap可以向我们显示的全部。但是假设它只有2.5 GB。每个PTE八个字节大约为3.2亿个PTE。由于每个PTE都定义了一个页面(4K字节)的虚拟地址空间,这意味着内存页表定义了超过1.2 TB的虚拟地址空间。
这不是不可能,但是很多。
作为参考,在我的系统atm上,页表中有大约125 MB的RAM。这将仅指示大约65 GB的虚拟地址空间。我的实际虚拟使用率要高得多(仅用于进程时为125 TB),但这是因为大多数页表不在RAM中。“大页面”是我不应该在这里讨论的另一件事,它也可以帮助说明页面表大小与使用中的虚拟地址空间大小之间的不同比率。
因此:要找到罪魁祸首,我首先要在“性能监视器”中的“进程”类别下查找“虚拟字节”计数器值较高的进程。