繁体   English   中英

C#中字典的内存使用情况

[英]Memory usage of Dictionaries in C#

我有一些代码,我添加了一个嵌套字典,格式如下

Dictionary<string, Dictionary<string, Dictionary<string, float>>>

这样做后,我注意到我的应用程序的内存使用情况严重上升。 这些词典以经常重复的字符串为基础,并且有许多这些字典,大约有数十万字典。

为了解决这个问题,我假设重复的字符串占用了大量的内存。 我的解决方案是散列字符串并使用整数(我会保留彩虹表的一个副本,以便我可以在必要时反转哈希)

Dictionary<int, Dictionary<int, Dictionary<int, float>>>

所以我去了一个内存分析器,看看我能得到什么样的尺寸减小。 令我震惊的是,我实际上发现字符串存储的大小实际上更小(正常和包含)。

这对我来说没有直观意义。 即使编译器足够智能只存储字符串的一个副本并使用引用,我认为引用将是一个指针,它的大小是int的两倍。 我也没有使用任何String.Intern方法,所以我不知道这将如何实现(这里也是String.Intern正确的方法?)

我对引擎盖下发生的事情感到非常困惑,任何帮助都会受到赞赏

如果您的键和值是对象,则字典的每个元素的开销大约为20字节,每个字典还有几个字节。 这是键和值本身消耗的空间的补充。 如果你有值类型作为键和值,那么它是12个字节加上键所占用的空间和字典中每个项的值。 这是因为元素的数量等于内部字典容量。 但通常存在比元素更多的容量,因此浪费了空间。

浪费的空间通常是一个更高的相对百分比,如果你有很多字典与少量元素相比,如果你有一个字典有很多元素。 如果我按你的评论说,你的8个元素的词典的容量为11,含2个元素的词的容量为3,而10的元素的容量为11。

如果我理解你的嵌套计数,那么一个顶级字典将代表184个字典元素。 但是,如果我们计算未使用的容量,就空间消耗而言,它接近200。 每个顶级字典200 * 20 = 4000字节。 你有多少人? 你说成千上万的物体中有成千上万的它们。 每10,000个将消耗大约38 MB的字典开销。 添加到字典中存储的对象。

通过管理哈希码来尝试将其缩小的原因可能是一个原因,即如果没有大量重复引用键。 使用int键替换对象引用键不会更改字典开销量,而是添加新哈希代码集的存储。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM