尝试在HashSet<Int32>
中添加23997908th
项目时抛出System.OutOfMemoryException
类型的例外。OutOfMemoryException将更多项目添加到非常大的HashSet时<Int32>
我们需要维护一个整数大小为Int32
.MaxValue的高性能唯一集合,即2147483647
。 HashSet
的Int32
只能在其中存储23997907
项。寻找解决此问题的建议。
尝试在HashSet<Int32>
中添加23997908th
项目时抛出System.OutOfMemoryException
类型的例外。OutOfMemoryException将更多项目添加到非常大的HashSet时<Int32>
我们需要维护一个整数大小为Int32
.MaxValue的高性能唯一集合,即2147483647
。 HashSet
的Int32
只能在其中存储23997907
项。寻找解决此问题的建议。
HashSet(Of T)对象的容量是对象可容纳的元素的数量。对象的容量会随着元素的添加而自动增加。
,如果你使用的是64位系统,您可以通过在运行时环境中gcAllowVeryLargeObjects的enabled属性设置为true的Hashset增加的最大容量高达2个十亿 元素。
您可以从配置文件中启用此设置,
<configuration>
<runtime>
<gcAllowVeryLargeObjects enabled="true" />
</runtime>
</configuration>
入住此MSDN链接设置配置。
更新:
以上配置gcAllowVeryLargeObjects支持在Net框架4.5只。
Framework 4.5以上只有... – 2011-12-27 07:08:48
我突然对.NET 4.5感到兴奋。我已经碰到了2GB的限制太多次了。 – 2011-12-27 07:11:00
@MitchWheat:是的,我忘了提。更新我的答案。谢谢 – mehul9595 2011-12-27 07:19:57
HashSet
增加一倍。因此,当您在列表中有23,997,907个项目并尝试添加下一个项目时,它会尝试将其后备数组的大小加倍。并且该分配导致它超出可用内存。我假设你在32位系统上运行这个功能,因为在64位系统上,HashSet<object>
可以容纳8900万个物品。 32位运行时限制约为6170万项。
你需要做的是预先分配HashSet
来保存尽可能多的项目,你需要。遗憾的是,没有直接的方式来做到这一点。 HashSet
没有一个构造函数,它将预先分配给定的容量。
但是,您可以创建一个List
,用它初始化HashSet
,然后在HashSet
上调用Clear
。这最终会给你一个HashSet
,它没有任何项目,但是你所请求的最大容量。我在博客文章中展示了如何做到这一点:More on .NET Collection Sizes。
对HashSet
大小的限制是由于.NET中的两个千兆字节限制所致。没有一个对象可以大于两个千兆字节。由于分配开销,该数字实际上略小。
Dot net只允许在Int32列表中添加134,217,728个项目 – Debasis 2011-12-27 08:12:08
@Debasis:如果您在64位模式下运行,我期望列表
在这一点上,我认为你需要使用数据库来保存你的项目(或他们的哈希键),因为这是太多的项目存储在默认的.NET对象。您也可以编写一个与HashSet具有相同属性的自定义对象,但这可能会更麻烦,只是使用数据库表来存储散列。
为了解决这个问题,我创建了一个实现HashSet方法和属性(Contains,Add,Count,...)的类,并在后台保留一个HashSets数组来存储实际数据。第一个实现在每个HashSet中一个接一个地完成,并在满时移到数组中的下一个。最新采用散列键作为内部HashSet数组的索引。这对我来说效果很好,因为这些键非常随意,所以将值分配给HashSets数组非常平均。
出于纯粹的好奇心:你需要什么? – 2011-12-27 06:45:11
http://blog.mischel.com/2008/04/09/hashset-limitations/ – 2011-12-27 06:57:28
@MikeNakis:正如后文所述,我们需要保持一个高性能独特的整数集合来满足我们的一些要求 – Debasis 2011-12-27 07:00:56