【问题标题】:What are the memory limits of a HashSet?HashSet 的内存限制是多少?
【发布时间】:2017-03-13 11:10:52
【问题描述】:

C# 中Hashset<string> 的内存限制是什么?

我已经看到 .NET 每个对象的内存限制为 2Gb?这些信息仍然准确吗?它适用于 Hashsets 吗?

我目前正在开发一个适用于大型哈希集的应用程序,我已经看到,一旦我为 64 位环境构建 dll,我只有在我的 8GB RAM 笔记本电脑达到其内存限制时才会出现 OutOfMemory。

如果我有 16Gb RAM,对象会不会增加,直到达到硬件限制?

【问题讨论】:

  • 2GB 限制是针对单个对象的,例如会影响数组的最大大小。但是,如果您存储在哈希集中的T 是类,那么只有 32 位或 64 位引用存储在哈希集中,实际对象实例及其大小在哈希集。 OutOfMemory 通常意味着 .NET 确实内存不足,它绝不应该意味着某个任意对象决定这是它可以达到的最高值。
  • @LasseV.Karlsen 它可以合法地抛出,因为某些支持内部结构无法调整大小;不知道HastSet<T>是怎么实现的,但是可行
  • 很难想象这样一种场景,即在用完存储字符串的地址空间之前用完 HashSet。您必须存储小字符串,很难保持它们的唯一性。如果平均字符串长度为 10 个字符,那么仅字符串就需要 10 GB。顺便说一句,GC 非常粗糙。 64 位程序中的可用地址空间受到最大页面文件大小及其增长速度的限制。
  • 磁盘是总是需要大量内存的程序的解决方法。无论是分页文件、平面文件还是 dbase,实际上都没有任何区别。

标签: c# .net performance hashset bigdata


【解决方案1】:

每个对象有 2GB 的限制,但请记住,当它是类中的字段时,引用类型仅使用指针大小(x64 为 8 字节)。

数组内存大小计算如下(忽略固定开销):

对于结构类型的数组:

  • 数组内存大小 = #数组中的元素 * 每个元素的大小

对于引用类型的数组:

  • 数组内存大小 = #数组中的元素 * 参考大小(x8x 为 4 字节,x64 为 8 字节)

因此,HashSet 可以引用总计远超过 2GB 限制的对象。只是如果将类中每个字段占用的大小相加——引用类型为 64 位,结构类型为完整大小——它必须小于 2GB。

例如,您可以有一个包含 16x1GB 字节数组的类。

另请注意,可以将应用程序配置为允许大小大于 2GB 的数组 - 尽管一维数组中的最大元素数仍不能超过 2G (2*1024*1024*1024)。

我怀疑您存储在 HashSet 中的对象是引用类型,因此内部 HashSet 数组中的每个对象仅使用 64 位,而每个对象的完整大小远大于 64 位 -总大小超过 2GB。

查看HashSet的referencesource可以看出使用了以下数组:

private int[] m_buckets;
private Slot[] m_slots;

Slot 的定义如下:

internal struct Slot {
    internal int hashCode;      // Lower 31 bits of hash code, -1 if unused
    internal T value;
    internal int next;          // Index of next entry, -1 if last
}

T是引用类型时,看起来每个Slot结构在x64上占用24字节,这意味着当使用的槽数超过2GB/24 = 85M个元素时,HashSet会抛出OutOfMemory

(如果T 是一个结构,那么根据它的大小,你会很快耗尽内存。)

【讨论】:

  • @LaRage 由于您要存储字符串,因此在 OutOfMemory 之前,您可以存储大约 128*1024*1024 个字符串。如果您启用大对象,我认为您可以存储〜2 * 1024 * 1024 * 1024个,然后由于元素过多而出现异常。但是您需要对此进行测试才能确定!我真的不确定。
  • 请原谅我的无知,但是在 x64 上,Slot 结构不应该占用 24 个字节吗?与类不同,结构不会为紧凑性而打包/重新排序。
  • @mafu 你是对的 - 它应该是 24 字节。我会更新答案。
  • 顺便说一句,这太低了,这是微软 100% 的错,因为它有另一个“640K 应该对任何人都足够”的时刻
猜你喜欢
  • 2015-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-27
  • 1970-01-01
  • 1970-01-01
  • 2012-10-08
  • 2016-10-19
相关资源
最近更新 更多