C#中的列表大小限制

时间:2011-10-25 06:05:57

标签: c# list

这可能看起来很讨厌 但为什么我们在列表中的对象数量有这么短的限制。

我编写了以下代码来测试C#中的列表大小

    List<int> test = new List<int>();            
    long test1 = 0;
    try
    {
        while (true)
        {
            test.Add(1);
            test1++;
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(test1 + "   |   " + ex.Message);
    }

并且列表的大小只能是134217728

不是那么不公平:(如果我想添加对象甚至超过'整数'限制(我的意思是对象数> 2 ^ 32),那么什么是替代方式?

4 个答案:

答案 0 :(得分:56)

List<int>支持int[]。一旦无法分配更大的后备阵列,您将失败 - 请记住:

  • CLR中每个对象限制为2GB,即使是64位(编辑:从.NET 4.5开始,对于64位CLR可以避免这种情况 - 请参阅<gcAllowVeryLargeObjects>
  • 该列表将尝试分配一个大于其立即需要的支持数组,以便在不重新分配的情况下容纳以后的Add个请求。
  • 在重新分配期间,旧新阵列的总内存必须足够。

Capacity设置为将支持阵列置于理论极限附近的值可能会让您获得比自然增长更高的截止点,但肯定会有这个限制。

期望大约2 29 元素的限制(536,870,912) - 我有点惊讶你没有超过134,217,728。你实际拥有多少记忆?你使用的是什么版本的.NET,以及什么样的架构? (对于32位CLR,每个对象的限制可能是1GB,我无法确定。)

请注意,即使每个对象的限制不是问题,只要你有超过2个 31 元素,你就会遇到问题直接寻址这些元素使用List<T>,因为索引器的值为int

基本上,如果你想要一个超过int.MaxValue元素的集合,你需要自己编写,可能使用多个支持数组。您可能希望明确禁止删除和任意插入:)

答案 1 :(得分:6)

这是一个由Long而不是整数支持的BigList的令人难以置信的天真(并且未经测试)实现。我在大约5分钟内写了它,它没有实现可数或ilist,但它显示了在其他答案中提到的分区。是的,它在VB中,处理它:)

这需要一些非常认真的工作,并且在它实际可用之前进行调整,但它说明了这个想法。

Public Class BigList(Of T)
    Private mInternalLists As List(Of List(Of T))
    Private mPartitionSize As Integer = 1000000

    Private mSize As Long = 0

    Public Sub New()
        mInternalLists = New List(Of List(Of T))
    End Sub

    Public Sub Add(Item As T)
        mSize += 1

        Dim PartitionIndex As Integer = CInt(mSize \ mPartitionSize)

        Dim Partition As List(Of T)
        If mInternalLists.Count < PartitionIndex Then
            Partition = New List(Of T)
            mInternalLists.Add(Partition)
        Else
            Partition = mInternalLists(PartitionIndex)
        End If
        Partition.Add(Item)
    End Sub

    Default Public ReadOnly Property Item(Index As Long) As T
        Get
            Dim PartitionIndex As Integer = CInt(mSize \ mPartitionSize)
            Dim Partition As List(Of T)
            If mInternalLists.Count < PartitionIndex Then
                Throw New IndexOutOfRangeException
            Else
                Partition = mInternalLists(PartitionIndex)
            End If

            Return Partition(CInt(mSize Mod mPartitionSize))
        End Get
    End Property
End Class

答案 2 :(得分:1)

列表限制是~536,870,912字节(我机器上的1/2 MB(32位Win7,.NET 4.0))

你的加法整数(每个4个字节),所以限制是字节限制/ 4(~134,217,727)

答案 3 :(得分:0)

我没有测试它,但由于它的实现方式,LinkedList<T>应该可以添加更多元素而不是List<T>。但要注意它的缺点(例如调用Count)。