【问题标题】:OutOfMemoryException when adding more items to a very large HashSet<Int32>将更多项目添加到非常大的 HashSet<Int32> 时出现 OutOfMemoryException
【发布时间】:2012-01-28 08:07:17
【问题描述】:

尝试在HashSet&lt;Int32&gt; 中添加23997908th 项目时抛出System.OutOfMemoryException 类型的异常。

我们需要维护一个高性能唯一的整数大小集合Int32.MaxValue,即2147483647HashSetInt32 只能在其中存储 23997907 项目。正在寻找解决此问题的建议。

【问题讨论】:

标签: c# .net out-of-memory hashset


【解决方案1】:

HashSet(Of T) 对象的容量是该对象可以容纳的元素数。对象的容量会随着元素的添加而自动增加。

如果您使用的是 64 位系统,您可以将 Hashset 的最大容量增加到 20 亿 通过在运行时环境中将 gcAllowVeryLargeObjects 的 enabled 属性设置为 true 来获取元素。

您可以从配置文件中启用此设置,

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

检查此MSDN 链接以设置配置。

更新:

以上配置 gcAllowVeryLargeObjects 仅支持 .Net framework 4.5。

【讨论】:

  • 我突然对 .NET 4.5 更加兴奋了。我已经多次达到 2 GB 的限制。
  • @MitchWheat:是的,我忘了提。更新我的答案。谢谢
  • 以上配置 gcAllowVeryLargeObjects 仅在 .Net 框架 4.5 上支持。为什么我没有读到这一行……​​为什么……
  • @mehul9595 我试过这个 gcAllowVeryLargeObjects 参数,它仍然会在 2GB 标记附近产生 OOM 错误
【解决方案2】:

HashSet 翻倍增长。因此,当您在列表中有 23,997,907 个项目并尝试添加下一个项目时,它会尝试将其支持数组的大小加倍。并且该分配导致它超出可用内存。我假设您在 32 位系统上运行它,因为在 64 位系统上,HashSet&lt;object&gt; 可以容纳超过 8900 万个项目。 32 位运行时的限制约为 6170 万个项目。

您需要做的是预先分配HashSet 以容纳所需数量的物品。不幸的是,没有直接方法可以做到这一点。 HashSet 没有构造函数来预先分配给定的容量。

但是,您可以创建一个List,用它来初始化HashSet,然后在HashSet 上调用Clear。最终会为您提供一个 HashSet,其中没有任何项目,但您请求的最大容量。我在一篇博文中展示了如何做到这一点:More on .NET Collection Sizes

HashSet 大小的限制是由于 .NET 中的 2 GB 限制。没有单个对象可以大于 2 GB。由于分配开销,该数字实际上略小。

【讨论】:

  • Dot net 只允许在 Int32 列表中添加 134,217,728 个项目
  • @Debasis:如果您在 64 位模式下运行,我希望 List&lt;int&gt; 可以为您提供超过 5 亿个条目。您的 1.34 亿个项目占用了超过 512 兆字节的内存,这很容易超过您在 32 位运行时分配的内存。 1.34 亿非常接近您可以构建的最大 HashSet,即使在 64 位模式下也是如此。
【解决方案3】:

此时,我认为您需要使用数据库来保存您的项目(或它们的哈希键),因为在默认 .NET 对象中存储的项目太多。您还可以编写一个与 HashSet 具有相同属性的自定义对象,但这可能比仅使用数据库表存储哈希更麻烦。

【讨论】:

    【解决方案4】:

    为了解决这个问题,我创建了一个实现 HashSet 方法和属性(Contains、Add、Count...)的类,并在后台保留了一个 HashSet 数组来存储实际数据。第一个实现只是将每个 HashSet 一个接一个地最大化,并在满时移动到数组中的下一个。最新的将哈希键的 mod 作为内部 HashSet 数组的索引。这对我来说效果很好,因为键几乎是随机的,因此 HashSets 数组的值分布非常均匀。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多