- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我故意在一个简单的 C# 程序中泄漏内存,以了解有关 .NET 如何管理这方面的更多信息。这是使用 int[]
数组完成的,每个数组的大小为 1000 万,每 100 毫秒声明一次。数组的元素没有被“触动”——就像被赋值一样——为了不将数据带入进程的工作集中:
const int BlockSIZE = 10000000; // 10 million
const int noOfBlocks = 500;
int[][] intArray = new int[noOfBlocks][];
for (int k = 0; k < noOfBlocks; k++) {
intArray[k] = new int[BlockSIZE];
Console.WriteLine("Allocated (but not touched) for array {0}: {1} bytes", k, BlockSIZE);
System.Threading.Thread.Sleep(100);
}
我正在使用 VMMap(由 Mark Russinovich 构建的工具)来查看内存是如何分配的。该版本是最近的版本(3.25,2018 年发布),因此它了解托管堆。
Visual Studio 2015 在具有 8 GB RAM 的 x64 Windows 10 计算机上用于编译和生成 .exe
文件。根据项目构建部分中的 Platform target
设置,可以看到与内存分配方式相关的不同结果,如下所示。
当 Platform target
设置为 x86
时,提交的内存会增长直到接近 2 GB 标记,然后才会抛出内存不足错误。该值是预料之中的,因为 2 GB 是 x86 架构上用户虚拟地址空间的限制(我没有使用 IncreaseUserVA,这会将其提高到 3 GB 稍后编辑:这并不完全正确 - 请参阅下面 David 的回答)。 VMMap 在这种情况下的输出如下。正如预期的那样,大多数提交的数据都属于托管堆类别。
当 Platform target
设置为 x64
时,提交区域如预期的那样不断增长。最终,应用程序需要被终止,因为它一直在分配内存。这也是预料之中的,因为只要可用 ram + 页面文件的总量能够适应增长,64 位 Win10 机器的理论限制是每个用户虚拟地址空间 128 TB(受当前处理器的限制)因为他们只使用虚拟地址中可用的 64 位中的 48 位)。 VMMap 的输出如下。同样,大多数提交的字节都属于托管堆类别。
当 Platform target
设置为 Any CPU
并且勾选 Prefer 32-bit
- 这实际上是 Visual Studio 中的默认设置2015 - 结果并不那么简单。 首先,当提交的内存达到大约 3.5 GB 时,将抛出内存不足异常。 其次,托管堆中的私有(private)字节仅增长到大约 1.2 GB,之后私有(private)数据类别注册下一个分配的数据。 VMMap 的输出如下。
为什么分配发生在最后一段中描述的 Any CPU
+ Prefer 32-bit
设置?具体来说,为什么大量数据列在 Private Data 而不是 Managed Heap 下?
后期编辑:添加内联图片以提高清晰度。
最佳答案
LARGEADDRESSAWARE 在 Windows64 (wow64) 上的 Windows 下运行的 32 位进程具有 4GB 的用户模式虚拟地址空间 (VAS),因为内核内存是 64 位,并且不需要映射到 4GB 可寻址的 32 位指针。您无需使用 /3GB 开关
启动 Windows 即可获取它。
针对 X86 进行编译时,您可能希望在 32 位和 64 位平台上有相同的行为,因此不设置 LARGEADDRESSAWARE 标志是有意义的。这也可能是出于向后兼容性的考虑。在非常过去,一些 32 位库(错误地)使用指针的高位,因此历史上将 32 位程序限制为 2GB 是一种安全设置。
AnyCPU+Prefer 32 位是较新的设置,默认设置为 LARGEADDRESSAWARE,使您可以更好地访问 64 位平台上的资源。
关于c# - 'AnyCPU' 平台目标上的内存分配模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54543938/
这个问题已经有答案了: 已关闭11 年前。 Possible Duplicate: Loading x86 or x64 assembly 我正在尝试编译任何 CPU .NET 项目,但我必须链接 S
我故意在一个简单的 C# 程序中泄漏内存,以了解有关 .NET 如何管理这方面的更多信息。这是使用 int[] 数组完成的,每个数组的大小为 1000 万,每 100 毫秒声明一次。数组的元素没有被“
我正在为任何 CPU 编写应用程序。当我在 64 位 PC 上运行以下命令时,它将不起作用: System.Diagnostics.Process[] running = System.Diagnos
我的 C# 程序是使用 AnyCPU 选项编译的,我正在使用 P/Invoke 以这种方式调用 native API: [DllImport("kernel32.dll", SetLastError
我的应用程序是使用“Any CPU”配置构建的。该应用程序的 WIX 安装程序是使用 platform=x86 构建的,因此生成的 MSI 是 32 位的。 当我在 64 位 Windows 上运行
当尝试 AnyCPU 以外的其他目标时,我会遇到更多错误,并且依赖项更难以解决。 但是在选择 AnyCPU 目标时,我得到的错误较少。 是否建议始终为 Xamarin 项目选择此目标? 最佳答案 让我
当我使用我的一个库时,我发现了一些奇怪的东西!我有一个负责读取特定文件类型的类库。它的工作做得很好。 我在两个不同的项目(WPF 和控制台)中使用了这个类库项目中一个类的Read 方法。 我的发现:使
我们的产品基于大量 C++ 项目,但我们现在将 C# 项目用于前端。我们现在也在做 64 位版本。 我们的计划是将所有 C# dll 构建为 AnyCPU。 C# 项目将引用公共(public) bi
当运行的系统肯定是 64 位系统时,从 AnyCpu dll 引用 x64-dll 是否有效? 我在问,因为我在这里遇到问题,得到如下异常: "Could not load file or assem
我有一个从 C# 项目引用的托管 C++ dll。 C# 项目将被编译为 AnyCPU。有什么方法可以编译 32 位和 64 位版本的托管 C++ dll,然后告诉 C# 项目在运行时加载正确的版本,
为什么 Solace .Net API 不针对 AnyCPU?我比较了 Reflector 中的 SolaceSystems.Solclient.Messaging.dll 和 SolaceSyste
我有一个针对 .NET 4.5.2 上的“AnyCPU”平台构建的程序集但是当我在 64 位机器上运行程序集时,dll 正在采用 32 位形式,经过大量研究后,我开始了解这个 thing在 .NET
我使用 Microsoft 的 COM 服务器示例: Out-of-process C# COM server (CSExeCOMServer) 一个简单的控制台 COM 客户端应该只启动服务器并使用
我需要以编程方式确定程序集是 x86、x64 还是 AnyCPU?有一个几乎相同的 question , 但它提供的解决方案 Assembly assembly = Assembly.LoadFrom
这是 2 个函数,fun1接受 1 个参数,fun2需要 4 个额外的无用参数。当我针对 x64 时,fun1需要 4s 但 fun2耗时不到 1s。如果我针对 anycpu,那么两者都需要不到 1
我有一个为 .NET 2.0 编写并针对 的现有 C# 应用程序AnyCPU 在这一刻。它目前引用了一些我没有源代码的第三方 .NET DLL(我不确定它们是为 x86、x64 还是 AnyCPU 构
我花了很多时间试图弄清楚为什么我的项目在 TFS2010 上使用默认(空白)配置构建,但如果我将其设置为任何内容,则告诉我没有输出路径。 最后发现.csproj文件中的配置写成AnyCPU而对于 TF
我们正在使用似乎被编译为 AnyCPU 的第三方程序集。 但是,我们的应用程序的许多安装都会导致问题。此第三方程序集使用 oracle dataaccess 库,并且无法在仅安装 32 位 oracl
根据 this QA,在 64 位机器上运行时,使用 Any CPU 和 x64 构建的应用程序之间应该没有性能差异,但是当我专门为 x64 构建时,我发现我的用例的性能提高了一倍左右平台。 我的用例
我试图让 COM 启动我的进程外 .NET COM 服务器。如果服务器进程是用 x64 编译的,它就可以工作,但如果我使用 AnyCPU(这是我想要的),那么它会挂起一段时间并最终失败并返回 0x80
我是一名优秀的程序员,十分优秀!