【问题标题】:Maximum size of .NET arrays.NET 数组的最大大小
【发布时间】:2010-10-24 01:03:04
【问题描述】:

并不是说我永远需要这样做,但我想了解它是如何工作/不工作的。我用谷歌搜索了很多数组的最大长度,但实际上什么都找不到。

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());

我想一个后续问题是,如果有一个限制并且我在该限制之外进行初始化,为什么只在使用时创建时没有例外?这是编译器应该捕获的东西吗?

【问题讨论】:

标签: .net arrays


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    根据SpankyJ,.NET 2.0 的每个数组至少有 2 GB 的限制。 8 字节 (sizeof long) * ~2^31 = 16 GB(更不用说所需的实际内存)。至于溢出,我同意 marcc 这可能是因为数组应该是 int-indexed (参见例如this method 虽然我对此有点不确定,因为this overload 需要一个 Int64 长度的数组。这可能是仅在更高版本中可用的扩展。

    不过,总的来说,这主要是一个理论问题。任何真正依赖它的人都可能做错了什么。

    【讨论】:

      【解决方案3】:

      数组的底层 IL 操作码处理 IntPtr(在 IL 文档中称为 native int):

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

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

      但是,我只是在我的 64 位 PC 上尝试了此代码,并且在第一次分配时得到了 OutOfMemoryException,因此显然实际限制更小。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-04-06
        • 1970-01-01
        • 1970-01-01
        • 2011-09-03
        • 2011-01-20
        • 2015-11-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多