我在一个字典中保存了一个大缓存,值为IEnumerable<KeyValuePair<DateTime,Double>>
。 我定期从字典中删除项目并定期向字典添加项目。 不时地,我会遇到System.OutOfMemoryException异常。 我想知道为什么垃圾收集器不来帮助我?
我在一个字典中保存了一个大缓存,值为IEnumerable<KeyValuePair<DateTime,Double>>
。 我定期从字典中删除项目并定期向字典添加项目。 不时地,我会遇到System.OutOfMemoryException异常。 我想知道为什么垃圾收集器不来帮助我?
IEnumerable<T>
的实现。例如,如果你正在使用一个LinkedList
,那么每个元素都会有相当大的开销。即使这样,我也不会认为250万个KVP会成为问题。是什么让你相信是这个缓存引起了问题? - Jon Skeet既然您问为什么垃圾回收器不会拯救您,那我就给出一个答案。
使用带有垃圾回收器的编程语言/环境确实可以让您的生活更轻松,但并不意味着内存管理已经成为过去式。
如果在32位xp机器上分配超过2G的大块内存,则刚刚达到了.NET内存边界之一。保留2G的内存总是一个坏主意。
在内存受限的机器上运行巨大的数据库或类似的东西,您很快就会达到可用内存的边界。由于GC不知道操作系统的情况,所以它可能无法及时注意到低内存情况(创建像位图这样的巨大对象可能会触发此情况)。一旦将巨大对象设置为null,手动调用GC.Collect可以在这里提供很大的帮助。
在内存中保留一个大字典只是一个非常简单的描述。您能告诉我们集合中有哪些内容,以及理论上这些项目有多大吗?
如果您的意思是具有2,147,483,647个项目的大字典,则可能已经达到了整数大小限制。
总之:
我不确定,如果我错了,请原谅,但也许当字典大于85kB(如byte[90000])时,它会存储在大对象堆中。
就像Gabe所说:
我可以看到,也许大对象堆会变得碎片化,你将无法在某个点之后扩展字典
当LOH被分段时,有时没有足够的空间来存储具有连续地址的对象。这就是导致OutOfMemory异常的原因。更像是LOH中连续空间不足的异常。