dor*_*ido 5 .net c# performance hashset bigdata
Hashset<string>C# 中a 的内存限制是什么?
我看到 .NET 每个对象的内存限制为 2Gb?这些信息仍然准确吗?它适用于哈希集吗?
我目前正在开发一个与大型哈希集一起使用的应用程序,并且我发现,一旦我为 64 位环境构建了 dll,只有当我的 8GB RAM 笔记本电脑达到其内存限制时,我才会出现内存不足的情况。
如果我有 16Gb RAM,对象会增加直到达到硬件限制吗?
每个对象有 2GB 的限制,但请记住,当引用类型是类中的字段时,它仅使用指针大小(x64 为 8 字节)。
数组内存大小计算如下(忽略固定开销):
对于结构类型的数组:
对于引用类型的数组:
因此,HashSet 可以引用总计远远超过 2GB 限制的对象。只是,如果将类中每个字段占用的大小(引用类型的 64 位,以及结构类型的完整大小)相加,它必须小于 2GB。
例如,您可以有一个包含 16x1GB 字节数组的类。
另请注意,可以将应用程序配置为允许大小超过 2GB 的数组 - 尽管一维数组中的最大元素数仍然不能超过 2G (2*1024*1024*1024)。
我怀疑您存储在 HashSet 中的对象是引用类型,因此内部 HashSet 数组中的每个对象仅使用 64 位,而每个对象的完整大小远大于 64 位 - 这给出了总大小超过 2GB。
查看 HashSet 的参考源发现使用了以下数组:
private int[] m_buckets;
private Slot[] m_slots;
Run Code Online (Sandbox Code Playgroud)
其中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
}
Run Code Online (Sandbox Code Playgroud)
看起来每个Slot结构体在 x64 上T是引用类型时占用 24 个字节,这意味着当使用的槽数量超过 2GB/24 = 85M 元素时,HashSet 将抛出 OutOfMemory 异常
(如果T是一个结构体,那么根据它的大小,你会很快耗尽内存。)