![]() |
1
2
更新: 答案完全重写。原始答案包含通过分而治之找到任何系统上最大可能可寻址数组的方法,如果您感兴趣,请参阅此答案的历史记录。新的答案试图解释56字节的间隔。 在 his own answer ,az解释说,最大阵列大小限制为小于2GB容量,并有一些尝试和错误(或其他方法?)查找以下内容(摘要):
我不完全确定16字节和32字节的情况。如果数组是结构数组或内置类型,则该数组的总可用大小可能不同。我将强调1-8字节的类型大小(我也不太确定,见结论)。 数组的数据布局
为了理解为什么clr不允许
根据本文中的所有信息,可以得出32位系统中数组的以下布局: Single dimension, built-in type SSSSTTTTLLLL[...data...]0000 ^ sync block ^ type handle ^ length array ^ NULL
每个部分都是一个系统
Single dimension, built-in type SSSSSSSSTTTTTTTTLLLLLLLL[...data...]00000000 ^ sync block ^ type handle ^ length array ^ NULL 当它是一个对象数组(即字符串、类实例)时,布局看起来略有不同。如您所见,将添加数组中对象的类型句柄。 Single dimension, built-in type SSSSSSSSTTTTTTTTLLLLLLLLtttttttt[...data...]00000000 ^ sync block ^ type handle ^ length array ^ type handle array element type ^ NULL
进一步看,我们发现一个内置类型,或者实际上是任何结构类型,都会得到它自己的特定类型处理程序(所有
关于结构类型的注意事项:可能不总是应用填充,这可能使预测结构的实际大小变得困难。 仍然不是56字节…为了计算az答案的56字节,我必须做一些假设。我假设:
同步块放在变量指向的地址之前,这使得它 看起来它不是物体的一部分 .但事实上,我相信这是事实,而且它也接近内部2GB的限制。我们得到,对于64位系统,添加所有这些内容:
不是 五十六 然而。也许有人可以在调试期间查看内存视图,以检查64位窗口下数组的布局。 我猜是沿着这条线(挑选、混合和匹配)的东西:
结论
从我在这项小研究中收集到的资料来看,我认为
这些结论都不能解释为什么16或32字节的数据类型分别有48和32字节的间隙。 谢谢你的挑战性主题,在我的过程中学到了一些东西。也许有些人在发现这个新的答案与问题更相关(我最初误解了这一点,并为这可能导致的混乱道歉)时会放弃投票。 |
![]() |
2
2
所以,我运行了一个l i'l程序来找出一些硬值,这就是我发现的:
结果:
我可以看到每次大小复制时,实际大小和理论大小之间的差异都会折叠,但不是2的幂。有什么想法吗?
编辑:
|
![]() |
3
0
除非您[编译了anycpu或x64]并在x64进程[在x64计算机上]中运行,否则您的进程空间限制为2GB。这就是你可能遇到的。计算这个过程中的净空不是一门精确的科学。 (NITPICKERS角:有A/3GB开关和其他边缘箱的堆叠,影响这一点。此外,进程还需要分配虚拟或物理空间。关键是,目前,大多数人在每个进程中遇到操作系统的次数比任何.NET限制都要多) |
![]() |
4
0
更新: 我的 other answer contains the solution 但是我把这个留给了mono,c,clr链接和讨论线程的信息 数组的最大大小受整数大小的限制,而不是它所包含对象的大小。但是.NET中的任何对象都限制为2GB,句点(感谢Luke和See Edit),这限制了数组的总大小,即单个元素加上一点开销的总和。 它阻塞您的系统的原因是,嗯,系统的可用内存。而Win32进程的系统只允许使用2GB内存,其中的程序和clr甚至在启动数组之前就已经使用了相当多的内存。其余的可以用于阵列:
这取决于您的CLR是如何配置的,不管您是否耗尽了内存。例如,在ASP.NET下,默认情况下,您被绑定到计算机总可用内存的60%。
编辑:
This answer to a related post
深入研究了64位的主题和问题。在64位系统上是可能的,但只能使用解决方法。它指向
this excellent blog post on the subject
这说明
注1:其他CLR,即Mono,只允许大于2GB的对象。
注2:不是语言限制了你。这在C中编译得很好,但是试着对一台不加处理的机器进行处理是一个相当前卫的想法(坦率地说,数组类中保存长度的字段是
|
![]() |
5
-1
您还需要向每个sizeof(t)添加指针大小(system.intptr.size),以说明指向任何给定数组元素中对象的指针。 |