在VS

时间:2019-02-09 21:01:48

标签: c# .net visual-studio memory

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

当然,当使用默认的构建设置进行编译时(如下图VS 2019 Preview 2.1所示),当进程达到4 GB时,用户虚拟地址空间将用完。这是预料之中的,其原因已在here中进行了讨论。

enter image description here

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

我想了解的是为什么选择Any CPU/Prefer 32-bit作为默认构建选项。我还注意到VS 2015也具有相同的默认设置,很可能是自VS 11之后发布的每个版本,如here所述。

通常会问的问题是“什么是AnyCPU ...?”并得到了反复的回答(1 2 3 4 5),简要介绍了定位x86 / {{1 }} / x64。但是对于为什么Any CPU + Prefer 32-bit被选为VS中的默认设置,我还没有一个明确的答案。

请仔细阅读默认情况下针对x64进行构建的原因:

  • x64进程将使用更多内存:对于上述简单示例(Any CPU + Prefer 32-bit的数组),实际上并非如此。当然,对数组本身的引用将是双精度的(8个字节而不是4个字节),仅此而已。根据{{​​3}}(“内存管理”一章),页面表结构中的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位堆栈,因此从堆栈角度来看会导致更高的内存消耗。 "Windows Internals" book
  • 跨平台的可移植性:答案enter image description here(小心,在发明int之前)提供了指向here的链接(本文于2017年更新)写作)。被引用的文章还显示了兼容性矩阵,但这仅适用于UWP。特别是关于ARM体系结构是使用Prefer 32-bit进行构建输出的现成目标,MS recommendation的漂亮表对此提供了支持。 this answer也被大量引用,显示了.NET 4.5带来的更改以及对ARM的影响。
  • 与现有的32位应用程序不兼容:有人评论This article关于Office是一个问题,因为Office通常安装为32位。不过,没有更多的信息。
  • 已加载的程序集:尝试在x64进程内部或以其他方式加载x86程序集时,抛出BadImageFormatException。但是,在对here的注释中,声明了可以用64位进程加载用AnyCPU/Prefer 32-bit编译的程序集。 尽管如此,我仍未找到支持此内容的官方文章 后来编辑:可以很好地加载它;我已经详细介绍了此程序以及所有可能的程序集加载测试 this comment

最后,默认的Any CPU/Prefer 32-bit设置很可能是一个折衷方案,并且由于某些其他更重要的事情而牺牲了大容量(> 4 GB)的内存访问。

尽管在Win10上x64进程用户模式虚拟地址空间的限制是128 TB,并且4 GB的物理RAM在当今的入门级笔记本电脑中成为标准配置,因此可能失去所有额外RAM(最大物理内存)的优势。 Windows版本的内存限制为here)。

0 个答案:

没有答案