2012-05-02 59 views
8

我的一位同事確信Oracle的odp.net ado.net實現中存在內存泄漏。他寫了一個測試程序來測試這個理論,並調用處理每個對象以確定被多少內存被釋放後,執行以下操作:GC.Collect()和PerformanceCounter

PerformanceCounter p = new PerformanceCounter("Memory", "Available Bytes"); 

GC.Collect(); 
GC.WaitForPendingFinalizers(); 

float mem = p.NextValue(); 

得到的性能值與檢索到的值進行比較在處理物體之前。這會產生準確的結果嗎?

+10

不,這不是內存管理器的工作原理。在經歷了分配虛擬內存空間的麻煩之後,它將釋放的塊放回空閒塊列表中,準備稍後再次使用。 –

+0

您是否嘗試過使用ProcessExplorer來監控您的進程中的.NET內存和系統內存使用情況?你還沒有說明什麼樣的內存在泄漏...... – GregC

+0

我們不知道什麼類型的內存泄漏,這是測試原因的一部分,以確認是否存在問題。我的問題是確認測試是否有效。 – zaq

回答

2

我認爲最好的辦法是使用GC.GetTotalMemory(true)。您可以在分配對象之前調用它來記錄分配了多少內存。然後你創建你的對象,也許對它進行一些操作,處理它,確保沒有對它的引用(可能只是將局部變量設置爲null),然後再次調用它。

請威力返回的值可能不是完全準確的,每個文檔,該方法將返回:

一個數字,表示字節數的最好的逼近當前在託管內存分配。

之後,您可以比較這兩個值。如果您反覆執行此操作,則可以查看該對象是否實際泄露了託管內存。

當然,如果對象泄漏非託管內存,這將無濟於事。

另一種選擇是使用內存分析器,但如果知道內存可能泄漏的位置,那麼這可能是一種矯枉過正。

+0

感謝您關於如何更好地獲得結果的想法。這是否意味着我發佈的方法有問題?爲什麼這是一個更好的方法? – zaq

+2

是的,你的方法是錯誤的,請閱讀Hans Passant的評論。當CLR收集垃圾時,它通常不會將內存返回給系統,因此即使內存實際上已釋放,也可能看不到可用字節中的任何更改。 – svick