【问题标题】:Array declared with maximum size throws OutOfMemoryException in C#声明为最大大小的数组在 C# 中抛出 OutOfMemoryException
【发布时间】:2020-08-12 18:22:04
【问题描述】:

我知道类似的问题已经被问过很多次并且也得到了回答。 互联网上的许多文章都只指向一个答案,即。 int 值或 2147483647 的最大值。

内联是来自stackoverflow的几个链接:

What is the Maximum Size that an Array can hold?

Maximum size of string array in C#

但是,当我尝试检查相同的内容时,会抛出 OutOfMemoryException。事实上,我试图将大小减少 2 倍到 1073741823(抛出异常),4 倍到 536870911(抛出异常),8 倍到 268435455(程序执行良好,没有任何异常)。

测试代码:

using System;

namespace ConsoleApp
{
    class Program
    {
        static void Main()
        {
            int arraySize = Int32.MaxValue / 1; //Factor when set to 8, program executes without any exception
            int[] testArray = new int[arraySize];

            testArray[0] = 6;

            Console.WriteLine("Press Enter to finish.");
            Console.ReadLine();
        }
    }
}

看起来所有其他答案都指向一个理论值,即`2147483647。然而在实践中,情况并非总是如此。所以问题是,鉴于应用程序代码非常简单,只有一个数组和几次控制台调用,是否有可能弄清楚应用程序在多大的数组时会抛出 OutOfMemoryException。

【问题讨论】:

  • 哪个 .NET 版本?什么比特?你有gcAllowVeryLargeObjects吗?关键是您的应用程序需要能够分配 RAM 的连续数量的 arraySize*elementSize。如果做不到,它就会失败。 AFAIK 使用托管代码来预测是否会成功并非易事。这么大的数组有什么用呢?
  • Int32.MaxValue = 2147483647 大于数组的最大大小。
  • 您链接的第一个问题为您提供了所需的答案,您是否已全部阅读?
  • 最后,我怎么强调都不够:拥有巨大的向量通常是个坏主意,会伤害你,所以问“什么是我理论上可以拥有的最大阵列”通常表明有人(隐喻地)将猎枪指向他们的脚,并询问他们理论上可以使用的最强大的炮弹是什么。 一些相关的场景,但它们是小众的,并且经常借用非托管内存(也许使用Memory<T>/Span<T>)是一个更好的主意。
  • 如果您尝试使用类似 536,870,850 的数组大小,这可能会起作用(它使您略低于单个对象的 2GB 限制)。但是,您不能保证它会起作用,因为操作系统可能无法为您分配足够的连续内存。无法保证任何分配都会成功,但是分配越大,失败的可能性就会越高

标签: c# arrays data-structures


【解决方案1】:

默认情况下,NET 框架将任何对象的最大大小限制为 2 GB。如果启用相应的设置gcAllowVeryLargeObjects,则数组在 64 位平台上可以更大。

所以理论上,int 数组的限制应该在 536 870 912 个元素左右,但这并没有考虑到数组本身的内存占用,因此真正的限制必须更少。

另一个问题是数组需要分配在 contiguous 内存空间中。如果分配器找不到任何这样的空间,即使对象低于最大大小限制,您也会得到OutOfMemoryException

【讨论】:

  • 谢谢@InBetween。 “536 870 912”对我来说很有意义。我错过了 2GB 必须除以 4 的数学运算。这对我来说很有价值。
猜你喜欢
  • 1970-01-01
  • 2012-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多