将更多项添加到非常大的HashSet <Int32>时出现OutOfMemoryException

Deb*_*sis 12 .net c# out-of-memory hashset

System.OutOfMemoryException尝试23997908th在a中添加项时抛出了类型的异常HashSet<Int32>.

我们需要维护一个高性能的整数sizeof Int32.MaxValue ie的独特集合2147483647.HashSetInt32只能存储23997907在它的项目.寻找解决此问题的建议.

meh*_*595 15

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

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

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

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

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

更新:

上面的配置gcAllowVeryLargeObjects仅支持.Net framework 4.5.


Jim*_*hel 11

HashSet通过加倍增长.因此,当列表中有23,997,907个项目并尝试添加下一个项目时,它会尝试将其后备阵列的大小加倍.而这种分配导致它超过可用内存.我假设你在32位系统上运行它,因为在64位系统上,它HashSet<object>可以容纳超过8900万个项目.在32位运行时中,限制大约为6170万个项目.

您需要做的是预先分配HashSet以根据需要保留尽可能多的项目.不幸的是,没有直接的方法可以做到这一点.HashSet没有一个构造函数,它将使用给定的容量预先分配它.

你可以,但是,创建一个List,用它来初始化HashSet,然后调用ClearHashSet.最终会给你一个HashSet没有项目的东西,但是你要求的最大容量.我在博客文章中展示了如何做到这一点:有关.NET Collection Sizes的更多信息.

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