为什么 'Any CPU (prefer 32-bit)' 允许我在 .NET 4.5 下分配比 x86 更多的内存?

Why does 'Any CPU (prefer 32-bit)' allow me to allocate more memory than x86 under .NET 4.5?

根据许多 SO 答案和 this widely cited blog post,为 'Any CPU' 构建并选择了 'prefer 32-bit' 选项的 .NET 4.5 应用程序将 运行 作为 32 位进程在 32 位和 64 位系统上(与 .NET 4.0 和更早版本不同)。 换句话说,选择了'prefer 32-bit'的x86和AnyCPU是等价的(忽略它是否可以在ARM上运行)。

但是,我的测试表明,在 64 位系统上,'AnyCPU prefer 32-bit' 应用程序(我确认 运行s 32 位)可以分配比 x86 应用程序更多的内存。我编写了一个 .NET 4.5 C# 控制台应用程序,它在一个循环中分配 10MB 字节数组(当然保留引用)直到它遇到 OutOfMemoryException,并且 运行 它在具有大量 RAM 的 64 位系统上。当构建为 x86 时,它会在分配的大约 1.2GB 处下降。构建为 'Any CPU (prefer 32-bit)' 的相同代码最多可达 1.5GB。

为什么不同?

事实证明,在 Visual Studio 2015 年,构建为 'AnyCPU (prefer 32-bit)' 会在可执行文件上设置 IMAGE_FILE_LARGE_ADDRESS_AWARE 位(相当于 运行 editbin /LARGEADDRESSAWARE它),而它不适用于 x86 构建。这可以通过 dumpbin /HEADERS 并查找行 "Application can handle large (>2GB) addresses".

来确认

Visual Studio 2013 年情况并非如此。变化是 apparently undocumented

理论上,这应该给 CLR 额外的 2GB 空间。我不知道为什么可分配内存只增加了大约 300MB。