【问题标题】:What is the Maximum Size that an Array can hold?数组可以容纳的最大大小是多少?
【发布时间】:2010-11-26 08:58:55
【问题描述】:

在 C# 2008 中,数组可以容纳的最大大小是多少?

【问题讨论】:

    标签: c# arrays


    【解决方案1】:
    System.Int32.MaxValue
    

    假设您的意思是System.Array,即。任何通常定义的数组(int[] 等)。这是数组可以容纳的最大值数。每个值的大小仅受可用于保存它们的内存量或虚拟内存量的限制。

    强制执行此限制是因为System.Array 使用Int32 作为其索引器,因此只能使用Int32 的有效值。除此之外,只能使用正值(即>= 0)。这意味着数组大小的绝对最大上界是Int32 的值的绝对最大上界,Int32.MaxValue 中提供,相当于 2^31,或大约 20 亿。

    另一方面,如果您对此感到担忧,则很可能您正在使用 大量 数据,无论是否正确。在这种情况下,我会考虑使用 List<T> 而不是数组,以便您只使用所需的内存。事实上,我建议一直使用List<T> 或其他通用集合类型。这意味着只会分配您实际使用的内存,但您可以像使用普通数组一样使用它。

    另一个笔记集合是Dictionary<int, T>,您也可以像普通数组一样使用它,但只会稀疏地填充。例如,在下面的代码中,只会创建一个元素,而不是数组创建的 1000 个元素:

    Dictionary<int, string> foo = new Dictionary<int, string>();
    foo[1000] = "Hello world!";
    Console.WriteLine(foo[1000]);
    

    使用Dictionary 还可以让您控制索引器的类型,并允许您使用负值。对于绝对最大大小的稀疏数组,您可以使用Dictionary&lt;ulong, T&gt;,这将提供比您想象的更多的潜在元素。

    【讨论】:

    • 这是真的,我现在将添加一些关于列表的内容,但这是一个有趣的问题,尤其是当您开始制作自己的可索引类时,您可以使用 ie。 long 提供更多潜在价值,如果这对您来说是个问题。
    • 我很确定 .NET 还规定最大对象大小为 2GB。这意味着即使数组使用Int64 索引器,byte[] 数组中的最大元素数仍将限制为大约2^31int[] 数组中的最大元素数约为 (2^31)/4long[] 数组中的最大元素数约为 (2^31)/8 等。
    • 2 GB 的限制是真实的。请参阅此相关问题:stackoverflow.com/questions/1087982/…
    • 感谢使用 Dictionary 处理稀疏索引数据的想法。我一直在考虑优化我们当前的数组使用情况,这是一个很好的方法。
    • 这个答案是完全错误的......首先最大数组大小小于Int32.MaxValue - 正如其他人指出的那样,这是一个神奇的数字。这个神奇的数字常量取决于使用的 .Net 版本以及存储的类型是否为一个字节大小。其次,字典在内部使用数组,这意味着字典的内部结构与其值或键的类型无关,因此创建 Dictionary&lt;ulong, T&gt; 不会神奇地打破这个限制。
    【解决方案2】:

    根据 MSDN,它是

    默认情况下,数组的最大大小为 2 GB (GB)。

    在 64 位环境中,您可以通过在运行时环境中将 gcAllowVeryLargeObjects 配置元素的 enabled 属性设置为 true 来避免大小限制。

    但是,该数组的总数仍将限制为 40 亿个元素

    参考这里http://msdn.microsoft.com/en-us/library/System.Array(v=vs.110).aspx

    注意:这里我假设我们将有足够的硬件 RAM,从而关注数组的实际长度。

    【讨论】:

    • 这是 .Net 4.5 中添加的新功能
    【解决方案3】:

    这个答案是关于 .NET 4.5

    According to MSDN,字节数组的索引不能大于 2147483591。对于 .NET 4.5 之前的版本,它也是数组的内存限制。在 .NET 4.5 中,这个最大值是相同的,但对于其他类型,它可以达到 2146435071。

    这是用于说明的代码:

        static void Main(string[] args)
        {
            // -----------------------------------------------
            // Pre .NET 4.5 or gcAllowVeryLargeObjects unset
            const int twoGig = 2147483591; // magic number from .NET
    
            var type = typeof(int);          // type to use
            var size = Marshal.SizeOf(type); // type size
            var num = twoGig / size;         // max element count
    
            var arr20 = Array.CreateInstance(type, num);
            var arr21 = new byte[num];
    
            // -----------------------------------------------
            // .NET 4.5 with x64 and gcAllowVeryLargeObjects set
            var arr451 = new byte[2147483591];
            var arr452 = Array.CreateInstance(typeof(int), 2146435071);
            var arr453 = new byte[2146435071]; // another magic number
    
            return;
        }
    

    【讨论】:

      【解决方案4】:

      以下是对您问题的详细回答: http://www.velocityreviews.com/forums/t372598-maximum-size-of-byte-array.html

      您可能需要提及您使用的 .NET 版本和内存大小。

      对于您的应用程序,您将被困在 2G 上,但有限制,因此这取决于您的阵列中的内容。

      【讨论】:

        【解决方案5】:

        我认为它与您的 RAM(或可能是虚拟内存)空间相关联,并且绝对最大值受限于您的操作系统版本(例如 32 位或 64 位)

        【讨论】:

        • 实际上,它受到索引值(int,或Int32)的限制。如果你不能容纳那么多,它会受到 RAM/VRAM 的限制。
        • 是的,我想我在你发布你的答案之前修改了我的答案。
        【解决方案6】:

        我认为如果不考虑VM,它是Integer.MaxValue

        【讨论】:

        • 如果您忽略 VM,原则上它是 Int64.MaxValue。尽管每个人都说索引是 32 位的,但这仅适用于使用 IL ldelem 指令之一的代码(而且过于迂腐,仅适用于 IL 本机 int 为 32 位的 VM。)但你不知道不必使用该指令。数组提供了接受 64 位参数的 GetValue 重载,因此原则上它支持 64 位索引。 CLR 不支持这个,所以在实践中,2GB 的限制仍然存在,但如果你忽略 VM,那么 System.Array 理论上支持更大。
        • @IanGriffiths:.NET int 和 uint 类型不是始终定义为 32 位,独立于硬件架构吗?是否允许更改“IL native int”的大小?
        猜你喜欢
        • 2010-12-17
        • 1970-01-01
        • 1970-01-01
        • 2023-03-13
        • 2012-09-24
        • 1970-01-01
        • 2013-01-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多