2010-04-22 68 views
5

我得到了OutOfMemoryException,應用程序運行1天后,應用程序完全使用1.5G內存,全部使用託管堆,第2代使用200mb,LOB使用1.3mb,但是事情是,900mb的空間是免費的。從perf計數器中我看到發生了第2代GC收集的數量,爲什麼GC收集器無法收集gen2和LOB中的900mb空閒空間?x86.net應用程序與system.OutOfMemoryException

我真的很想知道你的幫助。

以下信息來自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 
+1

今天我的錯誤。它來自無限循環-__- – 2010-04-22 21:46:59

+0

這是什麼類型的應用程序?你使用什麼樣的通信層? WCF? – 2010-05-25 15:58:33

回答

0

我不知道發生了什麼事情與第二代,但我相信大對象堆從不壓實 - 所以它可能是你有900MB有效的「差距」。只是猜測雖然,真的...

+0

是的,我同意你的說法,這是由於LOH造成的,因爲它沒有壓縮,我可以採用什麼方法解決? – Allen 2010-04-23 00:20:59

+4

@艾倫:有什麼辦法可以每12小時重新啓動一次?它不乾淨,但可能比其他任何工作都少。另一方面,調查爲什麼你有這麼多非常大的對象,並試圖減少這些並不是一個壞主意。 – 2010-04-23 05:26:34

0

可能是值得獲取內存分析器。 SciTech有一個很好的例子,在他們的網站上有關於如何發現潛在問題的教程。諸如不處置,或通過委託留下參考等內容可能會導致內存使用量增加。

0

我同意這是LOH的差距。

當我遇到這個問題時,我發現通常有一個或兩個集合被一遍又一遍地創建。

我使用的一種解決方案是創建一次集合,並將其初始化爲適合其最終將變爲大小的大小。這最初會增加初始內存使用量,但會減少outOfMemory異常。

2

如果你打算使用WinDBG/SOS,那麼學會使用它;)Tess Ferrandez在這個主題上的很多帖子都是非常寶貴的資源。

使用!dumpheap -stat來收集統計消耗堆的對象的類型(和數量)。

使用!dumpheap -min查找至少是字節大的對象。

使用!dumpheap標識當前駐留在堆中的對象。

使用!gcroot可以幫助找到任何可以讓您認爲死亡的物體保持活躍的根。

沒有關於您的應用和場景的一些細節,這很難進一步診斷。一些提示:

看看你是否有任何靜態容器或靜態對象包含很多東西。請記住 - 靜態對象活在應用程序的生命中。因此,靜態容器在應用程序的整個生命週期中生活,如果它們引用了應該被刪除的對象,那麼這些對象將繼續存在。

此外,請注意,您的應用程序可能會消耗大量的RAM,因爲可能有大量的可用RAM,因此不值得收集和壓縮LOH。

這也可能被證明是非常有價值的: http://msdn.microsoft.com/en-us/magazine/cc534993.aspx