.Net中的非常大的集合会导致内存不足异常

Yin*_*Zhu 32 .net c# f# gcallowverylargeobjects

我正在测试.Net中的集合有多大.从技术上讲,任何集合对象都可以增长到物理内存的大小.

然后,我测试的服务器,它具有16GB内存下面的代码,运行Windows 2003 Server和Visual Studio 2008,我测试两个F#和C#代码,看了看任务管理器运行时.我可以看到,在增加2GB内存之后,该程序因内存不足异常而崩溃.我确实在属性页面中将目标平台设置为x64.

open System.Collections.Generic

let d = new Dictionary<int, int>()

for i=1 to 1000000000 do
    d.Add(i,i)
Run Code Online (Sandbox Code Playgroud)

我对C5集合库进行了相同的测试.结果是C5中的字典可能耗尽整个内存.代码使用C5:

let d = C5.HashDictionary<int, int> ()
for i=1 to 1000000000 do
    d.Add(i,i)
Run Code Online (Sandbox Code Playgroud)

谁知道为什么?

Luk*_*keH 42

Microsoft CLR具有2GB的最大对象大小限制,即使是64位版本也是如此.(我不确定这个限制是否也存在于Mono等其他实现中.)

该限制适用于每个单个对象 - 而不是所有对象的总大小 - 这意味着使用某种复合集合进行解决方法相对容易.

这里有一个讨论和一些示例代码......

似乎很少有官方文档提到这个限制.毕竟,它只是当前CLR的实现细节.我所知道的唯一提及是在这个页面上:

在64位Windows操作系统上运行64位托管应用程序时,可以创建不超过2千兆字节(GB)的对象.


Mar*_*ell 21

在4.5之前的.NET版本中,最大对象大小为2GB.从4.5开始,如果启用了gcAllowVeryLargeObjects,则可以分配更大的对象.请注意,限制string不受影响,但"数组"也应涵盖"列表",因为列表由数组支持.


Ste*_*ont 11

为了清楚起见,Dictionary使用单个数组来添加对.它每次充满时会增长(加倍?).当有512万个对象时,它的大小为2GByte(具有32位对象指针,并假设完美分布).添加一个元素会使Dictionary尝试再次将数组大小加倍.繁荣.

C5 HashDictionary使用线性散列,并且可能使用每个包含多个(16?)元素的桶数组.它应该在以后遇到同样的问题.