2009-05-05 133 views
3

不是我永远不需要这样做,但我想了解它是如何工作/不工作的。我搜索了一个数组的最大长度,并且找不到任何东西。.NET阵列的最大尺寸

long[] hugeArray = new long[long.MaxValue]; 

//No exceptions 
Console.WriteLine("Init"); 

//Overflow exception 
Console.WriteLine(hugeArray.LongLength.ToString()); 

hugeArray = new long[int.MaxValue]; 

//OutOfMemoryException 
Console.WriteLine(hugeArray.Length.ToString()); 

而且我想跟进的问题是,如果有一个限制,我认为初始化限制之外,为什么没有例外使用时只产生什么时候?这是编译器应该捕获的东西吗?

+0

可能的重复[在64位Windows上的.NET中数组的最大长度是多少](http://stackoverflow.com/questions/2338778/what-is-the-maximum-length-of-an -array-在净上64位视窗) – skolima 2012-08-27 07:24:18

回答

3

根据SpankyJ,.NET 2.0至少有每个阵列2 GB的限制。 8字节(sizeof long)*〜2^31 = 16千兆字节(更不用说需要实际的内存)。至于溢出,我同意marcc,这可能是因为数组预计会被int-indexed(请参阅,例如this method虽然我对此有点不确定,因为this overload需要一个Int64长度数组,这可能只是一个扩展在以后的版本。

,总的来说,这主要是一个理论问题。没有人真的依靠这可能是做错了什么。

0

数组的索引是int,不长。所以,我想技术上新的long [int.MaxValue]将是最大的。但是如果你真的用完了内存,你仍然可以看到OutOfMemoryException。你在32位操作系统上运行这个吗?没有设定的最大长度,除了索引值是一个int,不是一个长。

5

底层的IL操作码的阵列处理IntPtr(被称为本地INT in the IL documentation):

  • newarr创建一个数组,并且接受一个IntPtr
  • ldelemstelem读写元件,并且它们使用IntPtr索引
  • ldlen返回一个数组的长度,并将它返回一个无符号IntPtr

我期望在32位平台上的2^31-1元素的数量和64位平台上的2^63-1的理论限制。

但是,我只是在我的64位PC上试过这个代码,在第一次分配时我得到了OutOfMemoryException,所以显然实际的限制更小。