我正在从这里学习Windows 32位虚拟内存页面映射,
(我的目标是现代Windows版本,如Vista,Win 7,Server 2003/2008 32位版本。)
两次混淆,
用户空间虚拟内存空间通常限制为2G,但物理磁盘页面存储空间可能远大于2G。由于磁盘页面多于虚拟内存页面,因此理论上可以将多个磁盘页面映射到一个虚拟地址页面。如果用户请求访问某个虚拟地址,如果有多个磁盘页映射到一个虚拟地址页,内存管理器如何知道应该访问哪个磁盘页?
我不知道为什么像byte []数组这样的限制必须使用连续的虚拟内存空间。我认为理论上即使我们只分配500M的虚拟空间地址,我们也可以重新使用这样的虚拟空间地址来继续映射/取消映射磁盘页面文件以消耗我们想要的数量,甚至大于2G。
< / LI> 醇>有什么想法吗?
答案 0 :(得分:2)
字节(或任何其他)数组必须使用连续的地址空间,在这种情况下是连续的虚拟地址空间。 这个区域可能会使碎片化成为一个问题,并且实际上会因内存虚拟化而加剧。由于此类系统系统中固有的各种“重定向”以及使其高效的性能考虑因素导致实际分配映射到块(通常是页面)中的虚拟地址空间的物理地址空间。
因此,请求10字节的虚拟地址空间块实际上可能会导致整个4K页面被保留和映射。由于页面中的物理内存必须是连续的,因此可能会导致整个4K的虚拟地址空间被“阻塞”。 可以在一个页面内放置多个小分配(优秀的内存管理器将尝试实现此目的)但实际上已经保留了超出严格要求的地址空间。考虑在页面的开始处分配单个字节,然后是4K-2个字节,然后是另一个单个字节。这占据了整个页面(有效) 考虑是否不再需要中间分配,因此被释放。在“顶部”和“尾部”值被释放或移动到其他地方之前,已经在虚拟地址空间中创建了间隙,该间隙只能由某些东西填充。 4K-1字节大小。 如果发生了足够的这类事情,虚拟地址空间中的连续区域比实际总实际使用的内存缩短得快。
你是正确的,没有什么能阻止你,用户将你的(限制在32位的地面)地址空间映射到CPU / OS支持的更大的磁盘或内存空间。有些芯片可通过PAE等机制实现超过4GB的物理地址空间。
Windows本身提供了一个API,用于处理“更改地址空间映射的大多数方面,以便在更广泛的池中获取不同的”窗口“(无论是通过PAE,运行WoW64,磁盘还是混合物)。这称为AWE。但是这样的机制已经存在多年了(正如那些记得EMS日期conventional memory或segmented memory日那样的人。
即使没有CPU和操作系统支持,您仍然可以通过各种技术亲自手动完成(见下文)。
Windows中的大部分更复杂的方面都是由有趣的Raymond Chen处理的。
答案 1 :(得分:1)
(对于某些版本的Windows,有一个开关可以为用户程序启用3G,但出于本讨论的目的,我们将忽略它,因为原理是相同的。)
32位程序只能访问4G内存,因为这是32位的最大指针。程序运行时,一些内存空间映射到自身,一些内存空间映射到操作系统。否则,当您调用操作系统时,操作系统代码无法同时看到自己的内存和程序内存。
所以你的程序没有所有的内存,因此限制了连续的分配。
现在,不同的程序可以拥有所有可寻址内存的不同子集。一些32位芯片允许物理上超过4G的内存,但是,任何给定的进程,因为它是32位,一次只能“看到”直接高达32位,或4G,其中一些属于该过程(2G) ),以及一些用于管理程序和其他程序的操作系统(2G)。
这是我能给出的简单解释;请参阅Virtual Memory了解更长,更技术性的解释。
答案 2 :(得分:1)
Mark Russinovich撰写了一篇好文章Pushing the Limits of Windows: Virtual Memory。我认为你应该阅读它以清楚地了解它是如何工作的。
答案 3 :(得分:0)
进程可用的总虚拟地址空间为4GB。其高2GB对所有进程都是通用的,只能由系统级组件访问。较低的2GB是每个进程专用的,不共享。这与RAM的大小完全无关。映射到用户进程的磁盘页面可能远远超过2GB。由于2GB进程空间是私有的,因此所有进程的总地址空间将远远超过2GB。即使在理论上,也不可能在同一进程中将多个磁盘页映射到一个虚拟地址。