将“任何 CPU/首选 32 位”设为 VS 中的默认构建设置背后的基本原理

2023-12-20

假设在 x64 Windows 机器上使用最新版本的 Visual Studio 和 C# 并分配大量数据。

果然,当使用默认构建设置进行编译时(如下图所示为 VS 2019 Preview 2.1),当进程达到 4 GB 时,您将耗尽用户虚拟地址空间。这是可以预料的,并讨论原因here https://stackoverflow.com/questions/54543938/memory-allocation-pattern-on-anycpu-platform-target.

分配本身可以通过创建数百个简单数组来完成,每个数组包含数百万个int元素。

我想了解的是为什么Any CPU/Prefer 32-bit被选为默认构建选项。我还注意到 VS 2015 也具有相同的默认设置,并且很可能自 VS 11 以来发布的每个版本都有相同的默认设置,如上所述here http://blogs.microsoft.co.il/sasha/2012/04/04/what-anycpu-really-means-as-of-net-45-and-visual-studio-11/.

通常问的问题是“什么是 AnyCPU...?”并且已经被多次回答(1 https://stackoverflow.com/questions/516730/what-does-the-visual-studio-any-cpu-target-mean 2 https://stackoverflow.com/questions/12066638/what-is-the-purpose-of-the-prefer-32-bit-setting-in-visual-studio-and-how-does 3 https://stackoverflow.com/questions/7508965/what-does-the-prefer-32-bit-compiler-flag-mean-for-visual-studio-c-vb 4 https://stackoverflow.com/questions/13149905/any-cpu-prefer-32-bit/13150845 5 https://stackoverflow.com/questions/5229768/c-sharp-compiling-for-32-64-bit-or-for-any-cpu),简单介绍一下定位的优点x86 / x64 / Any CPU + Prefer 32-bit。但我还没有找到明确的答案Any CPU + Prefer 32-bit选择为 VS 中的默认设置。

详细了解默认情况下反对构建 x64 的原因:

  • The x64 process will use more memory: for the simple example described above (arrays of arrays of int) this shouldn't really be the case. Sure, the reference to the array itself is going to be double (8 bytes instead of 4), but that's about it. As per the "Windows Internals" book https://blogs.msdn.microsoft.com/microsoft_press/2017/05/09/new-book-windows-internals-seventh-edition-part-1/ (Memory Management chapter), the PFN entries in the page table structures themselves are 64 bits wide on both x86 and x64 architectures, it's only that there are 3 (for x86) vs 4 (for x64) of levels of tables for resolving the virtual addresses to physical ones. As for the data referenced, it's the same size (4 bytes per int value). So allocating 20 arrays of 10 million int will roughly translate to 800 MB used for both architectures on the managed heap. Actually, the overall committed size on the x64 version of the simple example just described was about the same as the x86 one when tested (comparison follows, x64 on top, x86 below; and ignoring the 4 GB chunk that's simply in a reserved state for the x64 version). Interestingly enough, while running the 32 bit process on x64, each thread within the process will end up with 2 stacks, a 32-bit wow64 one and a 64-bit one, thus resulting in a higher memory consumption from the perspective of the stack. enter image description here
  • 跨平台可移植性:答案here https://stackoverflow.com/questions/516730/what-does-the-visual-studio-any-cpu-target-mean/2124096#2124096(小心,这是之前Prefer 32-bit选项被发明)提供了一个链接女士推荐 https://learn.microsoft.com/en-us/windows/uwp/packaging/device-architecture#x86(文章截至 2017 年撰写本文时更新)。引用的文章还显示了兼容性矩阵,但这仅适用于 UWP。特别是关于 ARM 架构作为使用构建的输出的开箱即用目​​标AnyCPU/Prefer 32-bit,这是由一个漂亮的表格支持的这个答案 https://stackoverflow.com/questions/516730/what-does-the-visual-studio-any-cpu-target-mean/41766077#41766077. 本文 http://blogs.microsoft.co.il/sasha/2012/04/04/what-anycpu-really-means-as-of-net-45-and-visual-studio-11/引用也颇多,展示了.NET 4.5带来的变化以及对ARM的影响。
  • 与现有 32 位应用程序不兼容:有人评论here https://stackoverflow.com/questions/12066638/what-is-the-purpose-of-the-prefer-32-bit-setting-in-visual-studio-and-how-does/12066861#12066861Office 是一个问题,因为它通常安装为 32 位。不过没有太多进一步的信息。
  • Loaded assemblies: A BadImageFormatException is thrown when trying to load an x86 assembly inside a x64 process or the other way around. However, within the comments to this comment https://stackoverflow.com/questions/12066638/what-is-the-purpose-of-the-prefer-32-bit-setting-in-visual-studio-and-how-does/12066861#12066861 it's stated that an assembly compiled with Any CPU/Prefer 32-bit can be loaded in a 64-bit process. I haven't been able to find an official article supporting this though later edit: It can be loaded just fine; I've detailed this and all possible tests for assembly loading here https://mihai-albert.com/2019/03/10/net-assembly-cross-bitness-loading/

最后还是默认的Any CPU/Prefer 32-bit设置很可能是一种权衡,并且以某种方式牺牲了大(> 4 GB)内存访问以换取其他被认为更重要的东西。

不过,Win10 上的 x64 进程用户模式虚拟地址空间的限制是 128 TB,并且 4 GB 物理 RAM 是当今入门级笔记本电脑的标配,因此可能会失去所有额外 RAM 的优势(对于Windows 版本有here https://learn.microsoft.com/en-us/windows/desktop/Memory/memory-limits-for-windows-releases).


None

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将“任何 CPU/首选 32 位”设为 VS 中的默认构建设置背后的基本原理 的相关文章

  • 提交后禁用按钮

    当用户提交付款表单并且发布表单的代码导致 Firefox 中出现重复发布时 我试图禁用按钮 去掉代码就不会出现这个问题 在firefox以外的任何浏览器中也不会出现这个问题 知道如何防止双重帖子吗 System Text StringBui
  • 在 DataView 的 RowFilter 中选择 DISTINCT

    我试图根据与另一个表的关系缩小 DataView 中的行范围 我使用的 RowFilter 如下 dv new DataView myDS myTable id IN SELECT DISTINCT parentID FROM myOthe
  • MVC 在布局代码之前执行视图代码并破坏我的脚本顺序

    我正在尝试将所有 javascript 包含内容移至页面底部 我正在将 MVC 与 Razor 一起使用 我编写了一个辅助方法来注册脚本 它按注册顺序保留脚本 并排除重复的内容 Html RegisterScript scripts som
  • ClickOnce 应用程序错误:部署和应用程序没有匹配的安全区域

    我在 IE 中使用 FireFox 和 Chrome 的 ClickOnce 应用程序时遇到问题 它工作正常 异常的详细信息是 PLATFORM VERSION INFO Windows 6 1 7600 0 Win32NT Common
  • 在 LINQ 中按 Id 连接多表和分组

    我想按categoryId显示列表产品的名称组 这是我的代码 我想要我的视图显示结果 Desktop PC HP Red PC Dell Yellow PC Asus Red SmartPhone Lumia 720 Blue 我的组模型
  • 如何在加载.NET WinForm应用程序user.config文件时捕获异常?

    有时 在使用默认配置系统的 NET 2 0 WinForm 桌面应用程序中 user config文件将被损坏并且无法再加载 当配置系统尝试加载它时 它会抛出一个System Xml XmlException 抛开 为什么文件首先被损坏 的
  • 在 C 中匹配二进制模式

    我目前正在开发一个 C 程序 需要解析一些定制的数据结构 幸运的是我知道它们是如何构造的 但是我不确定如何在 C 中实现我的解析器 每个结构的长度都是 32 位 并且每个结构都可以通过其二进制签名来识别 举个例子 有两个我感兴趣的特定结构
  • 使用 LINQ2SQL 在 ASP.NET MVC 中的各种模型存储库之间共享数据上下文

    我的应用程序中有 2 个存储库 每个存储库都有自己的数据上下文对象 最终结果是我尝试将从一个存储库检索到的对象附加到从另一个存储库检索到的对象 这会导致异常 Use 构造函数注入将 DataContext 注入每个存储库 public cl
  • 单个对象的 Monogame XNA 变换矩阵?

    我读过一些解释 XNA Monogame 变换矩阵的教程 问题是这些矩阵应用于 SpriteBatch Begin matrix 这意味着所有 Draw 代码都将被转换 如何将变换矩阵应用于单个可绘制对象 就我而言 我想转换滚动背景 使其自
  • 使用接口有什么好处?

    使用接口有什么用 我听说它用来代替多重继承 并且还可以用它来完成数据隐藏 还有其他优点吗 哪些地方使用了接口 程序员如何识别需要该接口 有什么区别explicit interface implementation and implicit
  • 是否有实用的理由使用“if (0 == p)”而不是“if (!p)”?

    我倾向于使用逻辑非运算符来编写 if 语句 if p some code 我周围的一些人倾向于使用显式比较 因此代码如下所示 if FOO p some code 其中 FOO 是其中之一false FALSE 0 0 0 NULL etc
  • 从 Linux 内核模块中调用用户空间函数

    我正在编写一个简单的 Linux 字符设备驱动程序 以通过 I O 端口将数据输出到硬件 我有一个执行浮点运算的函数来计算硬件的正确输出 不幸的是 这意味着我需要将此函数保留在用户空间中 因为 Linux 内核不能很好地处理浮点运算 这是设
  • 如何在 Xaml 文本中添加电子邮件链接?

    我在 Windows Phone 8 应用程序中有一些大文本 我希望其中有电子邮件链接 例如 mailto 功能 这是代码的一部分
  • 外键与独立关系 - Entity Framework 5 有改进吗?

    我读过了several http www ladislavmrnka com 2011 05 foreign key vs independent associations in ef 4 文章和问题 https stackoverflow
  • 如何设置 log4net 每天将我的文件记录到不同的文件夹中?

    我想将每天的所有日志保存在名为 YYYYMMdd 的文件夹中 log4net 应该根据系统日期时间处理创建新文件夹 我如何设置它 我想将一天中的所有日志保存到 n 个 1MB 的文件中 我不想重写旧文件 但想真正拥有一天中的所有日志 我该如
  • 将 MQTTNet 服务器与 MQTT.js 客户端结合使用

    我已经启动了一个 MQTT 服务器 就像this https github com chkr1011 MQTTnet tree master例子 该代码托管在 ASP Net Core 2 0 应用程序中 但我尝试过控制台应用程序 但没有成
  • 如何在非控制台应用程序中查看 cout 输出?

    输出到调试窗口似乎相当繁琐 我在哪里可以找到cout如果我正在编写非控制台信息 则输出 Like double i a b cout lt lt b lt lt endl I want to check out whether b is z
  • 如果没有抽象成员,基类是否应该标记为抽象?

    如果一个类没有抽象成员 可以将其标记为抽象吗 即使没有实际理由直接实例化它 除了单元测试 是的 将不应该实例化的基类显式标记为抽象是合理且有益的 即使在没有抽象方法的情况下也是如此 它强制执行通用准则来使非叶类抽象 它阻止其他程序员创建该类
  • 方法优化 - C#

    我开发了一种方法 允许我通过参数传入表 字符串 列数组 字符串 和值数组 对象 然后使用这些参数创建参数化查询 虽然它工作得很好 但代码的长度以及多个 for 循环散发出一种代码味道 特别是我觉得我用来在列和值之间插入逗号的方法可以用不同的
  • 如何将 PostgreSql 与 EntityFramework 6.0.2 集成? [复制]

    这个问题在这里已经有答案了 我收到以下错误 实体框架提供程序类型的 实例 成员 Npgsql NpgsqlServices Npgsql 版本 2 0 14 2 文化 中性 PublicKeyToken 5d8b90d52f46fda7 没

随机推荐