首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >集合和内存

集合和内存
EN

Stack Overflow用户
提问于 2011-03-25 13:56:03
回答 3查看 2.5K关注 0票数 0

我有一个应用程序,它读取3-4 GB的数据,从每一行中构建实体,然后将它们存储在列表中。

我遇到的问题是,内存变得疯狂,变得像13到15 GB。为什么存储这些实体需要这么多内存。

所以我构建了一棵树,并做了一些类似于Huffman编码的事情,总内存大小约为200 -300MB。

我明白,我压缩了数据。但我没想到在列表中存储对象会增加这么多内存。为什么会发生这种情况?

其他数据结构,如字典、堆栈、队列、数组等呢?

在哪里可以找到关于数据结构的内部结构和内存分配的更多信息?

还是我做错了什么?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-03-25 14:09:15

无论您将使用哪种数据结构,您的内存消耗永远不会低于存储所有数据所需的内存。

你计算过存储一个实例类对象需要多少内存吗?

您的huffman编码是一种节省空间的优化,这意味着您可以自己消除类对象中的大量重复数据。这与您用来保存数据的数据结构无关。这取决于数据本身的结构,以便您可以利用不同的节省空间的策略(其中huffman编码是众多可能性中的一种,适用于消除常见前缀,用于存储数据的数据结构是树)。

现在,回到你的问题上。在不优化数据(即对象)的情况下,您可以注意一些事情来提高内存使用效率。

我们所有的物体都有相似的大小吗?

你是不是只是运行一个循环,动态分配内存,然后把它们插入到一个列表中,就像这样:

代码语言:javascript
复制
foreach (var obj in collection) { myList.Add(new myObject(obj)); }

在这种情况下,您的list对象将不断扩展。如果末尾没有足够的空闲内存来扩展列表,.NET将分配一个新的、更大的内存块,并将原始数组复制到新内存中。从本质上讲,您最终得到了两块内存--原始内存和新的扩展内存(现在保存列表)。多次执行此操作(显然您需要对GB的数据执行此操作),您将看到大量的碎片内存空间( of )。

只需一次性为整个列表分配足够的内存,这样会更好。

作为后记,我不禁想知道:你到底要如何搜索这个庞大的列表来找到你需要的东西?你不应该使用像二叉树或哈希表这样的东西来帮助你的搜索吗?也许你只是在读入所有的数据,对所有的数据进行一些处理,然后将它们写回……

票数 1
EN

Stack Overflow用户

发布于 2011-03-25 14:25:19

在.NET中,大对象位于未压缩的大对象堆中。Large是超过85,000字节的所有内容。当你增加你的列表时,它们可能会变得更大,一旦你超过了当前的容量,就必须重新分配。重新分配意味着它们很可能被放在堆的末尾。所以你最终得到了一个非常零碎的LOH和大量的内存使用。

更新:如果您使用所需的容量(我想您可以从数据库中确定)来初始化列表,那么您的内存消耗应该会降低一点。

票数 2
EN

Stack Overflow用户

发布于 2011-03-25 14:16:27

如果您使用的是类,请阅读下面的响应:Understanding CLR object size between 32 bit vs 64 bit

64位(您使用的是64位,对吗?)对象开销是16字节加上对对象的引用(有人在引用他,对吗?)所以又是8个字节。因此,一个空对象将“吃掉”至少24个字节。

如果您使用的是Lists,请记住Lists是通过加倍的方式增长的,因此您可能会浪费很多空间。其他.NET集合也以同样的方式增长。

我要补充的是,数以百万计的List的“纯粹”开销可能会让他的记忆崩溃。除了List对象“吃掉”的16 +8字节的空间之外,它(在.NET实现中)由2个it (8字节)、一个SyncLock引用(8字节,通常为空)和一个对内部数组的引用(所以8+ 16字节+数组)组成。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5429039

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档