在.NET中,如果集合中的项目数量很大,它们是否容易被存储在LOH(大对象堆)中?
我对List和Dictionary特别感兴趣。在我的代码中,我将大量(40k+)相对较小的对象(假设为1k)存储在临时列表和字典中进行处理。这些集合中的项目数量是否增加了放入LOH的可能性?
对于List来说,假设List是作为双向链表实现的,那么元素数量不应该增加实际List对象的大小,但我想确切知道。
谢谢!
在.NET中,如果集合中的项目数量很大,它们是否容易被存储在LOH(大对象堆)中?
我对List和Dictionary特别感兴趣。在我的代码中,我将大量(40k+)相对较小的对象(假设为1k)存储在临时列表和字典中进行处理。这些集合中的项目数量是否增加了放入LOH的可能性?
对于List来说,假设List是作为双向链表实现的,那么元素数量不应该增加实际List对象的大小,但我想确切知道。
谢谢!
只有当对象大小超过85,000字节时,它们才会存储在LOH上。一个大的列表(特别是由结构体组成的列表)通常会被分配到这里。
然而,字典不太可能存储在LOH上,因为它们存储了一系列桶(bucket)的数组。除非生成足够多的桶使得数组大于85000字节,否则不太可能出现。即使是40k元素的类列表(因为每个元素中的对象引用将导致该列表在x86系统上达到160k,在x64系统上达到320k),也将存储在LOH上。但是每个单独的元素仍然会在标准堆(standard heap)上,因此会被压缩等处理。
如果使用双向链表而不是标准列表(List),则它很少存储在LOH上。列表的每个元素都很小(只是一个带有对下一个/上一个节点的引用的单个节点),因此没有单个对象大于85k字节。
有关LOH的详细信息,这篇博客文章讲得很好。
System.Collections.Generic.List
是以数组形式实现的,而不是链表。如果集合的大小较大,则会分配到大对象堆(请注意,数组的大小很重要,如果您有一个大型引用类型的小数组,则不会分配到 LOH)。
List被实现为一个数组。因此,该数组将被放入LOH中,但List对象本身不会。
同样地,Dictionary也是这样。它也在内部使用桶的数组,这些桶基本上存储您添加的键/值对。
字典具有O(LOG N)向量用于键/值,因此在40K+对象中您非常安全。 如前所述,列表被实现为数组,因此大型列表确实位于LOH上。 您可以使用SOS检查对象是否在LOH上。