"AnyCPU"平台目标上的内存分配模式 [英] Memory Allocation Pattern On 'AnyCPU' Platform Target

查看:89
本文介绍了"AnyCPU"平台目标上的内存分配模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我故意在一个简单的C#程序中泄漏内存,以了解更多有关.NET如何管理此方面的信息.这是使用int[]数组完成的,每个数组的大小为1000万,每100ms声明一次.为了不将数据带入流程的工作集中,未触摸"数组的元素(如分配值一样):

I'm purposefully leaking memory inside a simple C# program, to understand more about how .NET manages this aspect. This is done using int[] arrays, each with a size of 10 million, being declared every 100ms. The elements of the arrays are not "touched" - as in assigned a value -, in order not to bring the data in the process's working set:

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年发布),因此它了解托管堆.

I'm using VMMap (the tool built by Mark Russinovich) to see how the memory is being allocated. The version is a recent one (3.25, released in 2018), so it knows about the managed heap.

Visual Studio 2015在具有8 GB RAM的x64 Windows 10计算机上使用,以编译和生成.exe文件.根据项目构建"部分中的Platform target设置,可以看到与内存分配方式有关的不同结果,如下所示.

Visual Studio 2015 is used on a x64 Windows 10 machine with 8 GB of RAM to compile and generate the .exe file. Depending on the Platform target setting within the project's Build section, different outcomes relating to how memory is allocated can be seen, as follows.

Platform target设置为x86时,在抛出内存不足错误之前,提交的内存将增长到接近2 GB标记.该值是可以预期的,因为x86体系结构上的用户虚拟地址空间限制为2 GB(我没有使用GrowthUserVA,这会使该空间增加到3 GB. 稍后编辑 >:这并不完全正确-请参阅下面的大卫的回答).在这种情况下,VMMap的输出如下.正如预期的那样,大多数已提交数据都属于托管堆"类别.

When Platform target is set to x86, the committed memory grows until close to the 2 GB mark, before throwing an out-of-memory error. The value is to be expected, since 2 GB is the limit for user virtual address space on the x86 architecture (I'm not using IncreaseUserVA, which would have brought this up to 3 GB later edit: this is not entirely correct - see David's answer below). VMMap's output in this case is below. Most of the committed data falls under the Managed Heap category, as expected.

Platform target设置为x64时,承诺区域将按预期保持增长.最终,由于该应用程序不断分配内存,因此需要将其终止.这也是可以预料的,因为只要可用的ram +页面文件总数可以容纳增长,则64位Win10盒的理论限制是每个用户虚拟地址空间128 TB(受当前处理器的限制)因为它们仅使用虚拟地址中可用的64位中的48位). VMMap的输出如下.同样,大多数已提交的字节都属于托管堆"类别.

When Platform target is set to x64, the committed area keeps growing, as expected. Eventually the app needs to be killed since it keeps allocating memory. This was also expected, since as long as the total quantity of available ram + paging file(s) can accommodate the growth, the theoretical limit on a 64-bit Win10 box is 128 TB per user virtual address space (as limited by current processors since they are only using 48 bits of the 64 available within a virtual address). VMMap's output is below. Again, most of the committed bytes fall under the Managed Heap category.

Platform target设置为Any CPU并选中Prefer 32-bit时-这实际上是Visual Studio 2015中的默认设置-结果并非如此简单. 首先,当提交的内存达到约3.5 GB时,将引发内存不足异常. 第二,托管堆中的专用字节仅增长到约1.2 GB,此后,专用数据"类别将注册接下来要分配的数据. VMMap的输出如下.

When Platform target is set to Any CPU and the Prefer 32-bit is ticked - this actually being the default setting in Visual Studio 2015 - the outcome is not so straightforward. First of all, an out-of-memory exception is thrown when the committed memory goes to about 3.5 GB. Secondly, the private bytes within the Managed Heap only grow to about 1.2 GB, after which the Private Data category registers the data that is being allocated next. VMMap's output below.

为什么如上段所述为Any CPU + Prefer 32-bit设置进行分配?具体来说,为什么在私有数据"下而不是托管堆"下列出大量数据?

Why is the allocation happening as described in the last paragraph for the Any CPU + Prefer 32-bit setting ? Specifically why is a considerable amount of data listed under Private Data instead of Managed Heap ?

稍后编辑:内联添加了图片,以提高清晰度.

Later Edit: Added the pictures inline for better clarity.

推荐答案

在Windows 64(wow64)上的Windows下运行的32位进程具有4GB的用户模式虚拟地址空间(VAS),因为内核内存为64bit,并且没有无需映射到可使用32位指针寻址的4GB内存.而且您不必使用/3GB switch引导Windows即可获取它.

LARGEADDRESSAWARE 32bit processes running under Windows on Windows64 (wow64) have 4GB of user-mode Virtual Address Space (VAS), as the kernel memory is 64bit, and doesn't need to be mapped into the 4GB addressable with 32bit pointers. And you don't have to boot Windows with the /3GB switch to get it.

针对X86进行编译时,您可能会期望在32位和64位平台上具有相同的行为,因此不要设置LARGEADDRESSAWARE标志是有意义的.同样,这可能是由于向后兼容所致.在非常时代,一些32位库(误用)使用了高位指针,因此从历史上讲,将32位程序限制为2GB是一种安全设置.

When compiling for X86 you might expect identical behavior on 32bit and 64bit platforms, so it makes sense to not set the LARGEADDRESSAWARE flag. Also this was probably compelled by backwards compatibility. In the very old days some 32bit libraries (mis)used the high-order bit of pointers, and so historically restricting 32bit programs to 2GB was a safety setting.

AnyCPU +首选32位是一个较新的设置,默认情况下已设置LARGEADDRESSAWARE,以便您可以更好地访问64位平台上的资源.

The AnyCPU+Prefer 32 Bit is a newer setting, and gets the LARGEADDRESSAWARE set by default, to give you better access to resources on 64bit platforms.

这篇关于"AnyCPU"平台目标上的内存分配模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆