2011-09-07 164 views
0

我有一個C#應用程序循環通過一個數據表,並將它們推入一些位置,如Sage和一個SQL表。C#內存泄漏?

雖然它用於正常工作,但我現在莫名其妙地在運行一小時左右後出現內存不足異常。我已經注意到在任務管理器中,內存使用量每秒增加大約1mb,並且一直在繼續!

我的印象垃圾收集會帶來任何東西,但要確保我確保在使用它們之後處置任何對象。我知道沒有代碼很難診斷,但是它有很多,我正在尋找更多的一般建議。

+0

什麼版本的VS你有嗎?有了*更好的*,你可以使用探查器來試着找出你推入堆的什麼類型的對象 - 這將有很大的幫助。 – Carsten

+0

您是從您已經處理的DataTable中刪除行嗎? –

回答

3

但可以肯定我保證我用他們

的Dispose(處置後的任何對象)是沒有直接關係的內存管理或泄漏。

您必須查找仍然「可到達」的未使用對象。使用內存分析器來查明。

您可以從免費CLR-Profiler開始。

2

有一對夫婦的涌現在腦海潛在的問題:

  1. 有那剩下inelegible垃圾收集對象的大池(即,它們仍然是「可達」)。例如,如果您在每個循環中將對象添加到列表中,那麼列表將無限制地增長,並且只要該列表仍然可以訪問,列表中的每個元素都將無法用於垃圾回收。我並不是說這就是發生了什麼事,這只是內存如何分配然後離開而不被收集的例子。
  2. 由於某種原因,垃圾收集器沒有進行收集。
  3. 高內存使用實際上是由於您在應用程序中使用了非託管組件(例如,通過P/Invoke或COM interop)。

沒有看到任何代碼的技巧就如何解決您的問題但是通過Investigating Memory Issues閱讀應該給你如何給自己診斷內存問題的一些指針具體建議。特別是,我的第一步可能是檢查性能計數器以查看垃圾收集器是否實際運行,並檢查各種堆大小。

注意DisposeIDisposable接口無關內存使用 - 它的重要,因爲它釋放了所有相關資源,一旦你與他們進行處置,如數據庫連接對象(如處理),但是配置實現IDisposable對象對內存使用不太可能產生影響。

1

垃圾收集只能擺脫不再引用其他任何東西的對象。此外,它只能擺脫託管的對象 - 它無法控制由您可能與之交互的本機代碼創建的內存。因此這些是C#代碼中內存泄漏的兩個根本原因。

首先要看的是perfmon。獲取專用字節的計數器和進程的.net堆大小。如果堆大小保持不變(或上升和下降),但私有字節不斷增加,則您有一些本地代碼分配內存並且不釋放它。

如果堆大小隻是持續增長,那麼泄漏是在您的託管代碼中,您需要一個像ANTS,DotTrace或WinDbg(帶SOS擴展)的分析器來檢查堆並查看哪些對象在說謊。

1

.Net平臺上最受歡迎的「內存泄漏」是在某些無限循環中重複添加的被遺忘的集合。

0

當您爲臨時內存使用新內容時。

總是使用下面的方式,它確保調用處理。

using (Someclass A = new Someclass()) 
{ 
    ....something about A 
} 

SomeClass的是一個類實現的接口IDisposable的

GC也救不了你,如果有不安全的代碼,某些部分參與(P/Invoke的,玉米等),如果還有一個參考有些地方存在。

如果發現內存泄漏,使用WinDbg將會看到堆中有什麼。

本文可能會給你一些幫助。

http://www.codeproject.com/KB/dotnet/Memory_Leak_Detection.aspx