3

与此相关:

System.OutOfMemoryException 因为大字典

OutOfMemoryException当我让 .NET 管理我的字典时,我得到了。resize 方法中抛出的异常。所以我试图通过提供大量作为容量来避免调整大小。自然地,我试图从int.MaxValue只是为了确保它有助于解决问题。我计划尽可能多地下降。

然而OutOfMemoryException被抛出int.MaxValue。我决定进行一点二分搜索,构造函数接受的容量的第一个值变成了int.MaxValue / 32. 这不仅比我预期的要小,而且也令人困惑。

那么有没有人有任何想法为什么?

哦,项目设置设置为使用 x64 架构。

4

2 回答 2

9

的硬限制Dictionary<TKey, TValue>是由于entries具有类型的私有字段Entry[]。在这种情况下Entry是一个结构:

private struct Entry {
  public int hashCode;
  public int next;
  public TKey key;
  public TValue value;
}

的最小大小Entry为 4*4,如果TKey并且TValue都是 4 字节类型(指数组对齐大小,即CLIsizeof字节码指令返回的值),可能会发生这种情况。由于.NET 中的数组大小限制,这会导致int.MaxValue / (2*16)条目限制。如果您使用大于 4 个字节的or类型,则最大字典大小会相应减小。TKeyTValue

对于像您建议的大型词典,B+-tree 实现将更IDictionary<TKey, TValue>有效地利用系统资源,并且不受数组大小限制。

于 2013-08-21T17:28:03.880 回答
2

只是添加到 280Z28 的答案:

如果您真的必须拥有这么大的字典,并且您在 x64 上运行,并且您使用的是 .Net 4.5 或更高版本,那么您可以启用大对象支持。这将允许更大的字典。

在我的测试中,我可以指定一个容量高达int.MaxValue/2

为此,请在“app.config”文件中添加如下部分:

<runtime>
  <gcAllowVeryLargeObjects enabled="true" />
</runtime>

因此,您的整个“app.config”文件可能如下所示:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
  <runtime>
    <gcAllowVeryLargeObjects enabled="true" />
  </runtime>
</configuration>

有关详细信息,请参见此处:http: //msdn.microsoft.com/en-us/library/hh285054.aspx

于 2013-08-21T17:42:33.540 回答