我如何知道可以分配给定类型的.net数组的ACTUAL最大元素数?

reos 发布于 2019-11-10 .net 最后更新 2019-11-10 12:10 294 浏览

我知道.net中的所有数组都限制为2 GB,在此前提下,我尽量不要在数组中分配更多的n =((2 ^ 31) - 1)/ 8双精度值。尽管如此,这些元素似乎仍然不是有效的。任何人都知道如何在运行时确定给定sizeof(T)的元素的最大数量? 我知道无论接近这个数字的数量是多少,但是对于所有的意图和目的,我们可以说我需要它。 注意:我处于64位环境中,具有适用于我的AnyCPU应用程序的目标平台,并且RAM中至少有3100 MB空闲空间。 更新: 谢谢大家的贡献,对不起,我很安静。对于造成的不便,我们深表歉意。我一直无法改写我的问题,但我可以补充一点,我正在寻找的是解决这样的问题:

template <class T>
array<T>^ allocateAnUsableArrayWithTheMostElementsPossible(){
    return gcnew array<T>( ... );
}
结果在我自己的答案是有点令人满意,但不够好。此外,我还没有在另一台机器上进行测试(很难找到超过4 GB的另一台机器)。此外,我一直在自己做一些研究,看起来在运行时没有便宜的方法来计算。无论如何,这只是一个加号,没有一个我正在尝试完成的用户可以期望使用我尝试实现的功能,而不具有容量。 换句话说,我只是想了解为什么一个数组的最大元素数量不会加起来2GB的条件。现在我需要的是最高的最高限额。
已邀请:

bsequi

赞同来自:

内容太长未翻译

msed

赞同来自:

您的进程空间限制为2GB,除非您[编译了anycpu或x64]并在[x64计算机上]的x64进程中运行。这是你可能真正遇到的。无论如何,计算过程中的净空并不是一门精确的科学。 (Nitpickers转角:有一个/ 3GB的开关和其他边缘情况的堆栈会对此产生影响。此外,该过程还需要分配虚拟或物理空间。重点是,目前,大多数人会更多经常遇到操作系统的每个进程限制,而不是任何.NET限制)

mut

赞同来自:

您还需要将指针大小(System.IntPtr.Size)添加到每个sizeof(T),以考虑指向任何给定数组元素中对象的指针。

taut

赞同来自:

更新:我的other answer contains the solution,但我留下来了解有关Mono,C#,CLR链接和讨论主题的信息 数组的最大大小受整数大小的限制,而不受其包含的对象大小的限制。但.NET中的任何对象都限制为2GB,周期(感谢Luke并参见EDIT),它限制了数组的总大小,这是各个元素的总和加上一些开销。 它扼杀你的系统的原因是系统的可用内存。 win32进程的系统只允许你使用2GB的内存,你的程序和CLR在你启动数组之前已经使用了很多内存。您可以用于阵列的其余部分:

int alot = 640000000;
byte[] xxx = new byte[1U << 31 - alot];
这取决于您的CLR配置方式是否内存不足。例如,在ASP.NET下,默认情况下绑定到计算机总可用内存的60%。 编辑:This answer to a related post深入探讨了主题以及64位的问题。它可以在64位系统上使用,但只能使用变通方法。它指向this excellent blog post on the subject,它解释了BigArray<T>。 注1:其他CLR,即Mono,只允许大于2GB的物体。 注2:它不是限制你的语言。这在C#编译得很好,但是尝试并且没有投入它的机器是一个相当未来的思想(坦率地说,持有长度的Array类中的字段是int,这意味着它总是会抛出32位,但不一定,但极有可能,在任何64位实现上):
int[] xxx = new int[0xFFFFFFFFFFFFFFFF];  // 2^64-1

et_id

赞同来自:

所以,我运行了一个li'l程序来找出一些硬值,这就是我发现的:

  • 给定类型T,f(sizeof(T))= N + d
    • 其中f是实际最大尺寸 一系列的Ts。
    • N是理论上的 最大尺寸,即: Int32 :: MaxValue / sizeof(T)
    • 和d,是N和f(x)之间的差异。
结果:
  • f(1)= N - 56
  • f(2)= N - 28
  • f(4)= N - 14
  • f(8)= N - 7
  • f(16)= N -3
  • f(32)= N - 1
我可以看到,每次大小重复,实际大小和理论大小之间的差异折叠,但不是2的幂。任何想法为什么? 编辑:dT类型的数量。要以字节为单位查找d,请执行sizeof(T) * d