字典计数大于89478457时出错

Mot*_*tor 0 c# .net-core .net-core-rc2

我正在接受这个命令

Dictionary<UInt64, int> myIntDict = new Dictionary<UInt64, int>(89478458);
Run Code Online (Sandbox Code Playgroud)

这个错误:

System.OutOfMemoryException was unhandled  HResult=-2147024882
Message=Array dimensions exceeded supported range.
Source=mscorlib
StackTrace:
   at System.Collections.Generic.Dictionary`2.Initialize(Int32 capacity)
   at System.Collections.Generic.Dictionary`2..ctor(Int32 capacity, IEqualityComparer`1 comparer)
Run Code Online (Sandbox Code Playgroud)

在89478457上没有错误.以下是Dictionary.cs中Initialize的来源:

    private void Initialize(int capacity)
    {
        int size = HashHelpers.GetPrime(capacity);
        ...
        entries = new Entry[size];
        ...
    }
Run Code Online (Sandbox Code Playgroud)

当我重现它时,错误发生在数组创建上.在这种情况下,条目是一个结构,大小为24.当我们得到max int32(0x80000000-1)并除以24 = 89478485时,这个数字在素数89478457和89478503之间.

这是否意味着,结构数组不能像maxInt32/sizeOfThisStruct那样大?

编辑:

是.我实际上超过2 GB.当字典创建struct Entry的内部数组时,会发生这种情况,其中存储了(键,值)对.在我的例子中,sizeof(Entry)是24个字节,并且值类型是内联分配的.

解决方案是使用gcAllowVeryLargeObjects 标志(谢谢Evk).实际上在.net核心中,标志是环境变量 COMPlus_gcAllowVeryLargeObjects(谢谢svick).

是的,狗仔队是对的.我要思考,怎么不浪费记忆.谢谢你们.

Evk*_*Evk 7

.NET运行时存在已知的限制 - 堆上允许的最大对象大小为2 GB,即使在64位版本的运行时也是如此.但是,从.NET 4.5开始,配置选项允许您放宽此限制(仅限64位版本的运行时)并创建更大的阵列.启用它的配置示例如下:

<configuration>
  <runtime>
    <gcAllowVeryLargeObjects enabled="true" />
  </runtime>
</configuration>
Run Code Online (Sandbox Code Playgroud)