Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# System.OutOfMemoryException,因为字典太大_C#_Memory_Dictionary_Garbage Collection - Fatal编程技术网

C# System.OutOfMemoryException,因为字典太大

C# System.OutOfMemoryException,因为字典太大,c#,memory,dictionary,garbage-collection,C#,Memory,Dictionary,Garbage Collection,我在字典中保留了一个大缓存,其值为IEnumerable。我定期从字典中删除项目,并定期向字典中添加项目。偶尔我会得到一个System.OutOfMemoryException。我想知道为什么垃圾收集器不来救我 很有可能GC在很多时候都在帮助你,但有时你只是超出了它的能力 我想明确一点,这是一本字典还是一本字典?如果是后者,那么你可能还在其他地方保留参考资料 你的缓存有多大?你有监控来跟踪它吗?是什么让你认为是词典引起了这个问题?如果您可以控制缓存的数量,那么您是否尝试过减小大小?请记住,正如@

我在字典中保留了一个大缓存,其值为
IEnumerable
。我定期从字典中删除项目,并定期向字典中添加项目。偶尔我会得到一个System.OutOfMemoryException。我想知道为什么垃圾收集器不来救我

很有可能GC在很多时候都在帮助你,但有时你只是超出了它的能力

我想明确一点,这是一本
字典
还是一本
字典
?如果是后者,那么你可能还在其他地方保留参考资料


你的缓存有多大?你有监控来跟踪它吗?是什么让你认为是词典引起了这个问题?如果您可以控制缓存的数量,那么您是否尝试过减小大小?

请记住,正如@Gabe所提到的,堆可能会变得支离破碎。即使您可能有可用内存,它也可能没有足够大的块,无法在执行调整字典大小时分配给它

也许您可以使用patterns and practices库中的缓存块来帮助您实现良好的缓存。也许你可以选择一种不动态分配内存的算法,使用固定数量的条目


另外请注意,如果没有任何内存可供使用,那么问题在于缓存的大小,而不是垃圾收集器

既然你问GC为什么不救你,我就给你一个答案

使用带有垃圾收集器的编程语言/环境可以使您的生活更轻松,但不会使内存管理成为过去

如果你在32位xp机器上分配了超过2 gig的大内存块,你就达到了.Net内存的第一个边界。在内存中保留2G总是个坏主意

在内存有限的机器上运行一个巨大的数据库或类似的东西,您将很快达到可用内存的边界。由于GC不知道操作系统,它可能不会及时注意到内存不足的情况(创建位图之类的大型对象可能会触发这种情况)。手动调用GC.Collect,一旦你将一个巨大的对象设置为nothing,在这里会有很大帮助

在内存中保存一本大词典是一个非常简单的描述。你能告诉我们收藏品中有什么,理论上这些物品有多大吗

如果你指的是2147483647件这样的大东西,你可能已经达到了整数大小的限制

总而言之:

  • 不要将不需要的项目保留在内存中或将其交换到磁盘
  • 释放“大”项后,请调用GC.Collect(但不要在删除项的循环中,请在循环之后)

我不确定,如果我错了,请告诉我,但当字典大于85kB(比如一个字节[90000])时,它可能存储在大型对象堆中

正如盖布所说:

我可以看出,可能大型对象堆变得支离破碎,过了一个时点,您将无法扩展字典


当LOH被碎片化时,它有时没有足够的空间来存储具有连续地址的对象。这就是导致OutOfMemory异常的原因。它更像是LOH中的不连续空间例外。

缓存中保留了多少项?1000? 1000000? 我可以看出,可能是大型对象堆变得支离破碎,过了一点你就无法扩展字典了。你知道字典中存储的项目不会被垃圾收集,对吗?至少在它们被从字典中删除,以及任何其他引用被释放之前,我建议运行一个内存分析器来查看内存中保存了哪些对象。或者获取崩溃转储并检查堆的使用情况。为什么垃圾收集器不来救我?GC不会阻止你射中自己的脚;)哦,测量一下你的应用程序在性能计数器上使用了多少内存,这会告诉你发生了什么。我有一个包含500个元素的字典,每个元素都有一个SomeKeyType键,IEnumerable在每个元素中大约有5000个键值对。这就是5000*500,大约2500000 KVPs。从我收集的数据来看,DateTime是8字节,Double是8字节,即每个元素16字节,所以大约40兆字节。我完全不明白为什么我会有这样的问题。我倾向于在添加新的元素之前从字典中删除元素。@Anish:好吧,你还没有说你正在使用的是
IEnumerable
的什么实现。例如,如果您使用的是
LinkedList
,那么每个元素都会有相当大的开销。即便如此,我也不认为250万KVPs会成为一个问题。是什么让你相信是这个缓存导致了问题?