c# - 将“任何 CPU/首选 32 位”设置为 VS 中的默认构建设置背后的基本原理
问题描述
假设在 x64 Windows 机器上使用最新版本的 Visual Studio 和 C# 并分配大量数据。
果然,当使用默认构建设置进行编译时(下图为 VS 2019 Preview 2.1),当您的进程达到 4 GB 时,您将用完用户虚拟地址空间。这是意料之中的,原因在此讨论。
例如,分配本身可以通过创建几百个简单数组来完成,每个数组包含几百万个int
元素。
我想了解的是为什么Any CPU/Prefer 32-bit
选择它作为默认构建选项。我还注意到 VS 2015 也具有相同的默认设置,并且很可能是自 VS 11 以来出现的每个版本,如此处所述。
通常问的问题是“什么是 AnyCPU...?” 并且已经多次回答(1 2 3 4 5),简要介绍了定位x86
/ x64
/的优势Any CPU + Prefer 32-bit
。但是我还没有找到一个明确的答案来解释为什么Any CPU + Prefer 32-bit
在 VS 中被选为默认设置。
通过默认情况下反对为 x64 构建的原因:
- x64 进程将使用更多内存:对于上面描述的简单示例(数组的数组
int
),情况并非如此。当然,对数组本身的引用将是双倍的(8 个字节而不是 4 个),但仅此而已。根据“Windows Internals”一书(内存管理一章),页表结构中的 PFN 条目本身在 x86 和 x64 架构上都是 64 位宽,只是有 3 个(对于 x86)和 4 个(对于 x64)用于将虚拟地址解析为物理地址的表级别。至于引用的数据,它的大小相同(每个int
值 4 个字节)。所以分配20个1000万的数组int
将大致转换为用于托管堆上的两种架构的 800 MB。实际上,刚刚描述的简单示例的 x64 版本的总体提交大小在测试时与 x86 版本大致相同(比较如下,x64 在顶部,x86 在下面;忽略仅处于保留状态的 4 GB 块) x64 版本)。有趣的是,在 x64 上运行 32 位进程时,进程内的每个线程最终都会有 2 个堆栈,一个 32 位 wow64 一个和一个 64 位一个,因此从堆栈的角度来看,这会导致更高的内存消耗. - 跨平台的可移植性:此处的答案(小心,在
Prefer 32-bit
发明选项之前)提供了指向MS 推荐的链接(在撰写本文时,文章已于 2017 年更新)。引用的文章还显示了一个兼容性矩阵,但这仅适用于 UWP。特别是关于 ARM 体系结构是使用 构建输出的开箱即用目标, this answerAnyCPU/Prefer 32-bit
提供了一个不错的表来支持这一点。这篇文章也颇有参考价值,展示了.NET 4.5带来的变化以及对ARM的影响。 - 与现有的 32 位应用程序不兼容:这里有人评论说 Office 是一个问题,因为它通常安装为 32 位。虽然没有太多进一步的信息。
- 加载的程序集:尝试在 x64 进程中加载 x86 程序集或以其他方式加载时会引发 BadImageFormatException。但是,在对此评论的评论中,它指出编译的程序集
Any CPU/Prefer 32-bit
可以在 64 位进程中加载。虽然后来编辑,我还没有找到支持这一点的官方文章:它可以加载就好了;我已经详细说明了这个以及所有可能的程序集加载测试 here
最后,默认Any CPU/Prefer 32-bit
设置很可能是一种权衡,并且以某种方式牺牲了大(> 4 GB)内存访问以换取其他被认为更重要的东西。
虽然 Win10 上 x64 进程用户模式虚拟地址空间的限制是 128 TB,但 4 GB 的物理 RAM 是当今入门级笔记本电脑的标准配置,因此可能会失去所有额外 RAM 的优势(最大物理内存限制Windows 版本在这里)。
解决方案
推荐阅读
- tensorflow - models.set_weights() 给出无
- jenkins - 包含分支模式的条件不适用时的 Jenkinsfile
- mysql - 如何使用 HeidiSQL 通过 SSH 隧道连接到 MySQL unix socket?
- javascript - 如何将鼠标悬停在多个表格单元格上?
- google-chrome - HTML是否可以禁用自动完成“信用卡不支持消息”?
- r - 根据R中的关键字提取文本
- javascript - 更新被定义为较大对象中的变量引用位置的 JS 对象的一部分
- powershell - 具有数组属性的 Powershell pscustomobject 到 Csv 文件
- c# - 使用 google Api 编辑谷歌文档,无需在 c# 中上传到谷歌驱动器
- bootstrap-vue - 即使启用了 Bootstrap-Vue B-Form-Checkbox 也不会对点击做出反应