1

标题几乎概括了它。我有一个为 x86 平台编译的应用程序,它/largeaddressaware设置了标志。在 x64 系统上运行它,我“免费”获得了扩展的 4GB 用户模式虚拟内存,而无需指定/3GB引导选项。在 x86 系统上,这意味着内核模式内存只有 1GB,但由于 x64 系统可以处理更多内存,内核模式是否会保留 2GB 甚至增加到 3GB?

编辑:要清楚,我想知道每个进程的限制。这个问题源于阅读这篇文章

编辑 2:这个问题不是64 位操作系统上 32 位进程可以访问多少内存?因为该问题仅涉及应用程序可访问的内存,而不是系统可访问的内存。如果我有误解并且没有为每个进程的系统保留内存,如果有人能把它写下来作为答案,我将不胜感激。我相信我不是第一个对此感到困惑的人。

4

2 回答 2

4

有一些误解让你感到困惑。

首先,让我们看一下 32 位 Windows。每个进程的虚拟地址空间都有分配给进程本身的特定部分,以及内核需要的特定部分。但是,所有进程共享相同的内核内存 - 事实上,您甚至在自己的虚拟地址空间中都有内核内存,这基本上是一种性能优化,以避免在处理应用程序中的内核对象和数据时切换地址空间。

默认情况下,这是 1:1 拆分,因此您将获得 2 GiB 的用户地址空间和 2 GiB 的内核地址空间。这是(ab)被早期的 32 位 Windows 软件使用(当您的计算机可能只有 4 MiB 的内存和 486 CPU 或类似的),因为由于内存的布局方式,您的用户地址空间上面从来没有任何指针2 GiB 障碍 - 有效地为您提供任何指针的最高位,以供您自己的数据使用。通常这被用来允许混合“如果它适合,这是一个值,否则它是一个指向结构的指针”方法,节省内存和一些间接性。由于这种情况如此广泛,因此默认设置与早期相同,以防止出现兼容性问题。但是,您还可以选择加入不同的拆分 - 3 GiB 的用户空间和 1 GiB 的内核空间。这就是/3GB选项的作用。但这还不够——您的应用程序必须选择使用/LARGEADDRESSAWARE. 这基本上是说“我不会用我的指针做奇怪的事情”。

应该注意的是,32 位操作系统或进程并不一定意味着您只能寻址 4 GiB 的内存——它只是限制了 CPU 在任何时候可以直接访问的内容。对于内存密集型服务器软件,即使是“32 位”版本也可能支持寻址更多内存 - 例如,32 位 MS SQL Server 通过 AWE 支持高达 64 GiB。这基本上是另一层虚拟化,它允许重新映射虚拟地址的物理地址。从理论上讲,无论有没有 AWE,您可以寻址的内存量都没有限制 - 毕竟,没有什么能阻止您拥有自己的硬件作为内存映射文件,从而有效地为您提供无限的地址空间。当然,就像分段内存的时代一样,它不是很容易使用或实用:)

在 64 位 Windows 上,/3GB不再有意义并被忽略。默认地址空间拆分取决于 Windows 的确切版本,但在“TB 及更多”范围内,超出了 32 位限制。对于现代 Windows,这通常是 128 TiB 用户 + 128 TiB 内核。32 位应用程序仍然必须/LARGEADDRESSAWARE像以前一样使用。但是,由于内核现在是 64 位的,因此无论如何它都不能与用户进程位于同一地址空间,因此 64 位操作系统上的 32 位应用程序可以完全访问 4 GiB 的地址空间。

当然,这些限制仍然远低于 64 位理论上能够解决的问题。但是,大多数 64 位 CPU 实际上不能寻址整个 64 位地址空间 - 我上次检查时最常见的只是 48 位。惊喜,惊喜 - 为您提供 256 TiB 的地址空间,这是 Windows 的限制。毕竟不是微软的阴谋!:) 实际上,这并不是什么新鲜事。Intel x86 的 32 位 ALU 与 32 位地址空间相关联的事实在 CPU 历史上是一个异常值 - CPU 通常具有比其 ALU 宽度更高和更低的地址空间(用于虚拟寻址或物理寻址)宽度. MS DOS 1 MiB 可寻址内存的典型限制(640 kiB 留给用户应用程序)也来自此 - 当时的“32 位”CPU 只能使用 20 位地址。

于 2016-03-31T22:12:36.930 回答
0

如您链接到的文章中所述,32 位 CPU 上可用的 4GB 地址空间分为两部分:用户模式或应用程序地址空间,以及内核模式地址空间。

用户模式地址空间是每个进程的。每个进程在用户模式地址空间中的页面和物理或虚拟内存之间都有不同的映射。

无论当前正在运行哪个进程,内核模式地址空间都是相同的。否则,每次转换到内核模式时都必须重新映射地址空间,这将非常低效。(文章确实这么说,但只是非常简短:“操作系统使其虚拟内存在每个进程的地址空间中可见”。)

默认情况下,32 位 Windows 将其平均划分为 2GB 用户空间和 2GB 内核空间,但可以配置为将其划分为 3GB/1GB。

在 x64 Windows 上,内核以 64 位模式运行,因此它可以访问 CPU 允许的完整地址空间,目前为 48 位或 256TB。第一个 x64 Windows 版本仅使用 16TB 的地址空间,平均分配:8TB 用于应用程序地址空间(用于 64 位应用程序)和 8TB 用于内核。在 Windows 8.1 中,这增加了使用 CPU 允许的全部 256TB,再次平均分配:128TB 用于 64 位应用程序,128TB 用于内核。

32 位应用程序在 WOW64 仿真环境中运行,CPU 在传统模式下运行。但是,内核永远不会在传统模式下运行。当需要内核转换时,CPU 必须从 legacy 模式切换到 long 模式,这也意味着它从 32 位地址空间切换到 64 位地址空间。x64 CPU 的设计使这种转换是高效的。

因此,没有必要为内核保留任何32 位地址空间。

为确保向后兼容性,其可执行文件未标记为大地址感知的 32 位进程仍被限制为 2GB 的地址空间。如果可执行文件识别大地址,则该进程将获得全部 4GB。

您应该注意,这实际上是地址空间,而不是内存甚至虚拟内存。32 位应用程序可以使用文件映射和其他方法来使用超过 4GB 的内存。

您还应该注意,进程可以访问 2GB/3GB/4GB 的地址空间这一事实并不意味着应用程序可以使用所有这些空间。Windows 在每个进程中为自己保留一些用户模式地址空间。

地址空间和其他限制在此处记录:Windows 和 Windows Server 版本的内存限制

于 2016-03-31T22:24:23.847 回答