写的队列的容量是队列可以容纳的元素数。当元素添加到队列时,容量会根据需要通过重新分配自动增加。通过调用TrimToSize可以减少容量。
现在的问题是,在队列中,如果我们添加大约2万个项目,那么一个接一个队列将被排队,直到队列为空。如果我们不调用TrimToSize函数,那么队列大小将保持为20万,但数据被垃圾回收器删除,因此从技术上讲没有内存泄漏,如果我们检查计数或序列化队列,则大小为空队列。 那么我们为什么要调用TrimToSize函数呢?
答案 0 :(得分:3)
您将队列中对象的GC与队列本身的内存“插槽”混淆。
队列将分配空间来存储所有20K引用....这些插槽只是空的,因此不指向占用更多内存的对象。但那些“插槽”仍然存在,等待分配给他们的参考。
答案 1 :(得分:1)
根据两组对象进行思考:
queue other things
+------+
| slot | -> item
| slot | -> item
| slot | -> item
: :
| slot | -> item
+------+
虽然不再使用项目本身可能会被垃圾收集,但这不会影响单个对象,即仍在使用的队列。
然而,当你的负荷很高时,它可能会在某个时候扩展到数十亿个插槽,并且除非另有说明,它将保持这个尺寸。
通过调用队列中的TrimToSize
,可以减少正在使用的插槽的数量,可能会将内存释放回空闲池以用于其他目的。
即使没有添加大量元素,队列也会变得非常大,因为您可以为它配置高倍数(当您添加到完整队列时,其容量乘以的值)。
这一切都只是良好的内存管理,通常用于队列,你知道它们的大小不会再增加。
这方面的一个典型示例是从文件中读取配置项。一旦你读完它们,它们不太可能再次增大(直到你重新读取文件,这通常很少)。
如果您的队列可能经常在整个地方上下变化,那么使用TrimToSize
可能会更好。
答案 2 :(得分:1)
假设队列将项目存储在内部数组中,并且当容量增加时,将分配一个新数组,并将项目从旧的较小大小的数组移动到此新数组。
假设初始容量为16,则在内存中分配长度为16的数组。现在你的数组增长到20000,可能是因为算法出现了峰值,并且一旦处理完所有作业并且队列只包含1个项目。这次你使用的是20000长度的数组。在这种情况下,您的队列占用了太多的内存,然后需要。
队列主要用于长时间运行,任务管理的算法,其中内存使用将是非常动态的。减少容量将有助于提高性能,就好像你有很多实例并且每个实例都会长大,你将占用大部分内存。
看看这个场景,我更喜欢使用链接列表。
答案 3 :(得分:0)
容量不会逐一增加。如果我没记错的话,每当尺寸达到阈值时,容量就会翻倍。 TrimToSize将容量设置为完全相同的大小。
通常您不需要调用该方法。但是有些情况下你想要编组或序列化。
Andrew sais也是如此。
答案 4 :(得分:0)
队列使用对象[]来保存元素,所以即使你将所有元素出列在内存中你将拥有长度为20000的数组