我在应用程序运行1天后得到OutOfMemoryException,应用程序完全使用1.5G内存,全部由托管堆消耗,gen 2使用200mb,LOB使用1.3mb,但是我们想要的东西是,900mb的空间是免费的。从perf计数器我看到有一些gen 2 gc收集发生了,为什么GC收集器无法收集gen2和LOB中的那900mb可用空间?
我非常乐意为你提供帮助。
以下信息来自windbg:
0:000> !eeheap -gc
Number of GC Heaps: 1
generation 0 starts at 0x183153f0
generation 1 starts at 0x182aa834
generation 2 starts at 0x02131000
ephemeral segment allocation context: none
segment begin allocated size
02130000 02131000 0312f284 0xffe284(16769668)
07750000 07751000 0874fc5c 0xffec5c(16772188)
09e30000 09e31000 0ae2fc2c 0xffec2c(16772140)
0b230000 0b231000 0c22ffec 0xffefec(16773100)
0c230000 0c231000 0d22f6f0 0xffe6f0(16770800)
0d230000 0d231000 0e22ea10 0xffda10(16767504)
0e230000 0e231000 0f22c1c4 0xffb1c4(16757188)
10390000 10391000 1138ddf4 0xffcdf4(16764404)
154e0000 154e1000 164da90c 0xff990c(16750860)
34aa0000 34aa1000 35a9dbfc 0xffcbfc(16763900)
7aca0000 7aca1000 7bc9edfc 0xffddfc(16768508)
49760000 49761000 4a75ef64 0xffdf64(16768868)
7bca0000 7bca1000 7cc99bac 0xff8bac(16747436)
17a70000 17a71000 183313fc 0x8c03fc(9176060)
Large object heap starts at 0x03131000
segment begin allocated size
03130000 03131000 041250c8 0xff40c8(16728264)
08920000 08921000 099102f8 0xfef2f8(16708344)
....
....
4c760000 4c761000 4d71d578 0xfbc578(16500088)
1bb10000 1bb11000 1ca110d0 0xf000d0(15728848)
57760000 57761000 5862d7f8 0xecc7f8(15517688)
Total Size: Size: 0x5ab13450 (1521562704) bytes.
------------------------------
GC Heap Size: Size: 0x5ab13450 (1521562704) bytes.
0:000> !dumpheap -stat
total 0 objects
Statistics:
MT Count TotalSize Class Name
73037c78 1 12 System.Configuration.GenericEnumConverter
73036da0 1 12 System.Configuration.InfiniteIntConverter
....
....
69161c3c 35025 6809420 System.Windows.EffectiveValueEntry[]
69164748 54 12471072 MS.Internal.WeakEventTable+EventKey[]
710e2228 9540 190389260 System.Byte[]
710dd2b8 1317031 339257932 System.String
0035a670 6427 902224056 Free
Total 3615631 objects
答案 0 :(得分:2)
如果您打算使用WinDBG / SOS,那么学会使用它;)Tess Ferrandez关于这个主题的很多帖子都是非常宝贵的资源。
使用!dumpheap -stat收集消耗堆积的对象类型(和数量)的统计数据。
使用!dumpheap -min查找至少字节大的对象。
使用!dumpheap来识别当前堆在部分堆中的对象。
使用!gcroot帮助查找任何保持对象活着的根,你认为它们已经死了。
如果没有关于您的应用和您的方案的一些细节,那么很难进一步诊断。一些提示:
查看是否有任何包含大量内容的静态容器或静态对象。请记住 - 静态对象在应用程序的生命周期中存在。因此,静态容器在应用程序的生命周期中存在,如果它们引用了应该被删除的对象,那么对象将继续存在。
另外,请注意您的应用程序可能会消耗大量的RAM,因为可能有足够的可用RAM,因此收集和压缩LOH的成本不值得。
这也可能证明非常有价值: http://msdn.microsoft.com/en-us/magazine/cc534993.aspx
答案 1 :(得分:0)
我不知道gen2在那里发生了什么,但我相信大型对象堆永远不会被压缩 - 所以可能是你有效地获得了900MB的“空白”。只是一个猜测,真的......
答案 2 :(得分:0)
获得内存分析器可能是值得的。 SciTech有一个很好的,在他们的网站上有关如何找到潜在问题的教程。诸如不处理或通过代理留下引用等事情可能会使你的内存使用量增加。
答案 3 :(得分:0)
我同意这是LOH的差距。
当我遇到这个问题时,我发现通常会有一两个集合一次又一次地被创建。
我使用的一个解决方案是创建一次集合并将其初始化为适合最终变化的大小。这最初会破坏初始内存使用量,但会减少那些outOfMemory异常。