有人知道为什么在 32 位 Windows 系统中进程无法寻址 4GB 内存而只能寻址 2GB 吗?
这只是Windows系统的限制吗?
注意:我指的不是可寻址的总内存,而是单个进程可以寻址的内存。
为什么在 32 位 Windows 系统中进程无法寻址 4GB 内存
但他们肯定可以。 您的代码通常不具备寻址地址空间上部部分所需的访问权限。 用户模式代码在环 3 运行,要到达上部部分,您需要环 0 访问权限。 内核模式。
好吧,这有点开玩笑,具有 Ring 0 访问权限的操作系统内核和驱动程序通常不被认为是该进程的一部分。 尽管逻辑上是这样,但它们在每个进程中都映射到相同的地址。 从技术上讲,当进程从环 3 模式切换到环 0 模式时,动态映射页面是可能的,但这会使内核模式转换过于昂贵和麻烦。
直观地说:由 ReadFile() 填充的文件缓冲区可能有一个与操作系统代码或数据块重叠的地址。 最坏的情况是,它可能与文件系统驱动程序代码重叠。 或者,更可能的是文件系统缓存。 所需的翻页和双面复印会使阅读速度变慢。 最简单的架构选择是在 1992 年做出的,当时没有人有钱买得起 1GB RAM,就是简单地将地址空间一分为二,这样就不可能出现重叠。
这是一个已解决的问题,32 位版本的 Windows 越来越少,而 32 位进程可以在 64 位版本的 Windows 上寻址 4 GB。 它只需要 EXE 标头中的一个选项位,该选项位由链接器和 editbin.exe 中可用的 /LARGEADDRESSAWARE 选项设置。
理论上它可以提供更多可用空间(事实上,你可以告诉 Windows 让你拥有 ~3GB,尽管默认情况下它不会启用,以防某些软件/驱动程序/等出现问题),但你不会得到完整的 4GB,而不削弱操作系统高效运行系统的能力。
即使您在 Windows 上将用户空间空间扩展到 3GB,应用程序默认情况下也不会获得额外的范围。 Windows 要求应用程序设置一个标志(在 MSVC 下使用 /LARGEADDRESSAWARE 构建,不知道其他构建环境),或者将它们限制为 2GB,以避免软件对地址进行假设而导致的任何问题。