2011-08-16 189 views
2

我在.net中有一個應用程序,它獲得的內存越來越多。 我從團隊成員那裏得到了一些關於我的應用程序分配的最常見和最重的實例的分析。.net內存泄漏問題

enter image description here

的問題是,我不知道下一步該怎麼做。 源代碼是巨大的! 和我需要最佳實踐如何捕獲有問題的函數/代碼行。

p.s-我試過使用visual studio的「.net內存分配(採樣)」功能,但它總是無法創建報告。 (猜猜這可能是另一個問題)。

+0

順便說一句,你正在使用Visual Studio的哪個版本? – sll

+0

visual studio 2010 – Erez

回答

1

Visual Studio Profiler完全符合您的要求,它能夠在調用堆棧中顯示熱路徑。您必須學習如何使用Profiler,因此如果您無法生成Visual Studio Profiler報告並且無法調查如何執行此操作,則首先應該閱讀文檔,因爲無論您使用的是哪種工具。

下面是關於Visual Studio的分析器有用的鏈接:

編輯:熱路徑通過VS探查:

0

我最喜歡做的第一件事就是使用windbg和psscor2。 然後我做了!gcroot和/或!GCRef。這個有時提供洞察保持對象活着的基礎引用。

對不起該衝的回答,請例如this blog一些更多的參考,如果你不知道psscor2

0

如果我沒有記錯的話,它看起來像你的隊友已經在使用的WinDbg與託管擴展(也許是SOS?),並且打電話給!dumpheap -stat。獲取他的內存轉儲文件的副本,在WinDbg中打開並加載SOS。

第一步是深入研究特定的類型。就你而言,它看起來像你有一個非常大的字符串分配(大約84MB)。因此,嘗試通過運行看字符串列表:

!dumpheap -type System.String 

它將輸出字符串實例的名單。輸出會是這個樣子:

Address MT   Size Gen 
0x412d0030 0x79b94638 812 1 System.String XXXX 
0x422d0030 0x79b94638 812 1 System.String XXXX 
0x432d0030 0x79b94638 812 1 System.String XXXX 

該命令可能會幾分鐘運行,因爲你有很多字符串實例,但嘗試觀察,而其運行的輸出。如果您注意到很多實例具有相同的大小,那通常表明您沒有正確地釋放資源。任何這些實例都是下一步的理想選擇。如果在列表的末尾還可以看到大尺寸的字符串,這些也是下一步的好選擇。

下一步是檢查哪些對象正在引用特定的字符串實例並阻止它被垃圾收集。您可以通過使用從dumpheap輸出地址上方,然後調用做到這一點:

!gcroot 0x432d0030 

這將輸出類似這樣:

173866dc(System.Web.UI.WebControls.ListItemCollection)-> 
173866ec(System.Collections.ArrayList)-> 
173894b8(System.Object[])-> 
17386d0c(System.Web.UI.WebControls.ListItem)-> 
17386ce8(System.String) 

你可以閱讀從底部到頂部。所以在這個例子中,字符串保存,該列表項目又由對象保存。在這一點上,解決你的問題變得更加藝術。從該鏈的底部開始(包括字符串),並且對於每一行上行,請檢查是否可以將該對象存儲在內存中。如果沒有,那麼你應該找到一種方法來釋放該資源並將其收集起來。這一步很可能會要求您查看和分析每個課程的代碼。

提示:由於System.Action的實例數量異常多,因此很有可能訂閱了事件/多播委託,並且之後忘記取消訂閱。