2010-03-24 75 views
2

我知道有沒有簡單的回答我的問題,但我會很感激的想法,指南或 某種東西到查找在列表OutOfMemoryException異常 - 出出主意

我有網的Windows服務,是不斷拋出OutOfMemoryException。 該服務有兩個適用於x86和x64 Windows的版本。但是,在x64上,它會消耗更多的內存。我曾嘗試用各種內存分析器對其進行分析。但我無法弄清楚問題所在。診斷 - 服務在3到12小時後消耗大量VMSize並崩潰應用程序。行爲是相當隨機的 - 崩潰情景沒有可觀察的模式。

另外我試着看看性能計數器(perfmon.exe)。我可以看到, 堆大小正在增長,%GC時間平均爲19%。 Plus內存分配與%CPU時間相關。

我的應用程序有線程和鎖定對象,DB連接和WCF接口。 的一般問題,我試圖解決:

根本就沒有得到它GC足夠快 到GC對象或一些非管理 (窗口)對象正在消耗 內存?

見列表 http://s45.radikal.ru/i109/1003/af/92a389d189e8.jpg http://s45.radikal.ru/i109/1003/af/92a389d189e8.jpg

與性能計數器圖片鏈接第一個應用程序查看 http://s006.radikal.ru/i215/1003/0b/ddb3d6c80809.jpg

+0

在我看來,你有一些對象不是釋放(內存泄漏),或者你的CPU工作太多,框架決定不運行垃圾回收器。還可以查看MSDN垃圾收集器的延遲模式 - http://msdn.microsoft.com/zh-cn/library/bb384202.aspx。你到目前爲止使用了哪種內存分析器? – 2010-03-24 12:21:42

+0

你是從數據庫中查詢很多數據嗎? – AndrewC 2010-03-24 12:26:42

+0

嗨Mikael,我試過dotTrace和螞蟻。他們也崩潰(有時) 將看看你提供的鏈接。 – 2010-03-24 12:31:39

回答

7

是您的問題,你不知道什麼是消耗了大量的內存?當進程使用大量內存時,您可以打開任務管理器,右鍵單擊您的進程並創建一個可以在windbg中查看的轉儲文件,以準確找出分配內存的內容。

苔絲費蘭德斯有很多優秀的演示。 She goes through the most useful stuff here...

3

我用.Net Memory Profiler它比微軟的clr profiler好得多。你必須稍微瞭解一下。它可以告訴你哪個對象沒有處理或有參考。你也可以根據類型和內存對對象進行排序。我使用了最近30天的試用版,在此期間我能夠在我的應用程序中解決問題。

4

你的問題很可能是經典的泄漏(當它們不應該是根源的時候)或大對象堆(LOH)碎片。

我發現診斷此類問題的最佳工具是Windows調試器的Strike(SOS)擴展。下載微軟的Debugging Tools for Windows得到調試器:CDB是控制檯調試器(我更喜歡它,因爲它似乎更響應),WinDbg與MDI應用程序包裝的是相同的東西。這些工具是相當低級的,有一點學習曲線,但提供了你需要知道的一切來找到你的問題。

特別是,運行!DumpHeap -stat以查看哪些類型的對象正在吃掉你的記憶。如果該命令發現任何重要的碎片,該命令還會在列表底部報告。 !EEHeap將列出堆段 - 如果有很多的LOH段,那麼我會懷疑LOH分段。

0:000> .loadby sos mscorwks 
0:000> !EEHeap -gc 
Number of GC Heaps: 1 
generation 0 starts at 0x00f7a9b0 
generation 1 starts at 0x00e79c3c 
generation 2 starts at 0x00b21000 
ephemeral segment allocation context: none 
segment begin allocated  size 
00b20000 00b21000 010029bc 0x004e19bc(5118396) 
Large object heap starts at 0x01b21000 
segment begin allocated  size 
01b20000 01b21000 01b8ade0 0x00069de0(433632)  

如果有很多LOH片段,那麼我會開始懷疑LOH片段化。

之前這樣做,不過,我很想知道:

  1. 應用程序是否使用中的String.intern()?
  2. 應用程序是否具有訂閱具有長壽命對象的事件的臨時對象?

(我之所以問這是1. .NET串實習生表是在這樣一種方式,它們能引起LOH fragmenation和2事件訂閱提供了額外的根訂閱對象,它是實現容易忘記。)

+0

嗨Paul,CDB或WinDbg可以附加到運行進程嗎? – 2010-03-24 12:53:29

+0

是的,運行'CDB -pv -p 1234',其中1234是進程ID。 – 2010-03-24 12:54:57

+0

(另外,'q'退出調試器並解凍你的過程。) – 2010-03-24 12:55:31

1

如果你花在GC上的時間百分比很高,那麼我會看LOH分配perfmon計數器。如果LOH頻繁分配,這將導致GC努力收集,這是花費在GC上的百分比高的原因。

我做了關於identifying high CPU in GC because of LOH的博客,它展示瞭如何獲得在LOH中分配的確切的調用棧。

希望這會有所幫助。

相關問題