代码之家  ›  专栏  ›  技术社区  ›  Yin Zhu

Net中的超大集合导致内存不足异常

  •  31
  • Yin Zhu  · 技术社区  · 15 年前

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

    然后我在一台服务器上测试了以下代码,该服务器内存为16GB,运行windows2003server和visualstudio2008。我测试了F#和C#代码,并在运行时查看了任务管理器。我可以看到,大约增长2GB内存后,程序崩溃,出现内存不足的异常。我在属性页中将目标平台设置为x64。

    open System.Collections.Generic
    
    let d = new Dictionary<int, int>()
    
    for i=1 to 1000000000 do
        d.Add(i,i)
    

    我也做了同样的测试 C5 收藏图书馆。结果是C5中的词典可能会耗尽整个内存。代码使用C5:

    let d = C5.HashDictionary<int, int> ()
    for i=1 to 1000000000 do
        d.Add(i,i)
    

    有人知道为什么吗?

    4 回复  |  直到 9 年前
        1
  •  42
  •   LukeH    15 年前

    限制适用于每个 单一的 对象——不是所有对象的总大小——这意味着使用某种复合集合相对容易解决问题。

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

    似乎很少有官方文件提到这一限制。毕竟,它只是当前CLR的一个实现细节。我唯一知道的是 on this page :

    当您运行64位托管 64位Windows上的应用程序 对象的大小不超过2G

        2
  •  22
  •   Marc Gravell    13 年前

    在.NET 4.5之前的版本中,最大对象大小为2GB。从4.5版开始,如果 gcAllowVeryLargeObjects 已启用。请注意 string

        3
  •  11
  •   Stephan Eggermont    15 年前

    更清楚的是,字典使用单个数组来添加对。它生长(加倍?)每次都是满的。当有5.12亿个对象时,它的大小是2GByte(有一个32位的对象指针,并且假设完全分布)。再添加一个元素会使字典再次尝试将数组大小增加一倍。繁荣。

    C5 HashDictionary使用线性哈希,可能使用一个bucket数组,每个bucket包含多个(16?)元素。以后也会遇到同样的问题。

        4
  •  1
  •   itadapter DKh    8 年前

    当一个人需要存储很多对象时,你会看到的问题是 GC暂停(暂停)。我们所做的是从GC中“隐藏”数据,这变成了

    看这个: https://www.infoq.com/articles/Big-Memory-Part-3

    可以将缓存用作字典: https://github.com/aumcode/nfx/tree/master/Source/NFX/ApplicationModel/Pile

    请参见“缓存”部分

    推荐文章