2011-09-28 61 views
0

運行在32位計算機上的32位.net應用程序遇到OutOfMemoryException。然後我進行了一次完整的內存轉儲,儘管使用WinDbg我可以驗證是否有很多內存正在使用,但我想知道爲什麼我們會得到OOME,但根據WinDbg的輸出「!eeheap -gc」,GC堆大小是隻有1GB左右,所以看起來1.5GB的.net存在相當大的空間。OutOfMemoryException,轉儲文件大小和GC堆大小

這裏的是輸出的部分:

0:000> !eeheap -gc 
Number of GC Heaps: 1 
generation 0 starts at 0x6a12ffcc 
generation 1 starts at 0x6a12ffc0 
generation 2 starts at 0x016a1000 
ephemeral segment allocation context: (0x6a12ffd8, 0x6a12ffe4) 
segment begin allocated  size 
016a0000 016a1000 0269ff64 0x00ffef64(16772964) 
... 

69130000 69131000 6a12ffd8 0x00ffefd8(16773080) 
Large object heap starts at 0x026a1000 
segment begin allocated  size 
026a0000 026a1000 03698a98 0x00ff7a98(16743064) 
... 

70020000 70021000 70a7d750 0x00a5c750(10864464) 
Total Size 0x3c67abb4(1013427124) 
------------------------------ 
GC Heap Size 0x3c67abb4(1013427124) 

這是可以預料?剩餘的〜500MBs在哪裏?

更多的細節:

  • 轉儲文件本身的大小2.007.000.476字節。
  • 運行該軟件的計算機只有1GB的物理RAM,但該計算機的虛擬內存設置爲增長到3GB(因此該應用程序應該可以增長到最大爲1.5GB的32位。網絡應用程序)。

回答

1

最有可能的過程不知道3GB。這是每個過程設置。

此外,如果你想看到總的內存使用情況,你可以使用!堆-s。這會給你一個每個堆所做的事情和它使用的內存量的總結。這也會向你顯示碎片問題。將它與託管堆結合起來,它應該給你一個總內存使用的想法。

+0

如果我沒有弄錯,這個過程應該能夠達到1.5G。我的問題不是我想改變極限(如3GB)。順便說一句。從其他答案/評論,所以我覺得這是不可能的。我想知道如果不在.net堆中,其他500個左右的位置。我嘗試過!堆,但只有總計大約100MB(當我有更多時間時必須再次檢查,該命令的輸出需要一些適應) –

+0

您需要檢查儲備大小。這基本上告訴你該進程請求了多少進程地址空間。這很高是什麼會導致OOM錯誤。那麼這很簡單,但這是一個好的開始,並且將覆蓋90%的案例。 – Zipper

0

近2 Gb的轉儲大小表示進程的用戶地址空間已滿。內存不僅被.Net內存分配填充,還被填充爲本地(C/C++)分配,jitted代碼,二進制文件,堆棧,... 使用Windbg,使用!address -summary檢查虛擬空間的使用情況。 要獲得全局視圖,還可以使用DebugDiag分析轉儲。

+0

!address -summary告訴我,RegionUsageIsVAD使用1.917.264 KB /〜98%Pct(Busy)。不知道這對我有什麼幫助。 –

+0

VAD是通過VirtualAlloc未被識別爲win32堆分配的內存。一般來說.Net內存和來自Win32堆的大對象被標記爲VAD – plodoc

+0

你看過!eeheap的輸出(沒有-gc)來檢查加載器使用的內存嗎? – plodoc