2009-02-10 36 views
1

我寫了一個自動化測試,以確保我們的應用程序現在不會泄漏(管理&非託管內存),並隨着開發的不斷增長。問題是我的測試似乎不可靠,但我不知道這是.NET固有的,泄漏定義還是測試。如何以可靠且自動的方式測量.NET中的內存泄漏?

它發生是這樣的:

long start = PrivateBytes; 
// here is the code for an action which is expected to be memory-constant 
long difference= PrivateBytes-start; 
Console.WriteLine(difference); // or Assert(difference < MyLimit); 


private static long PrivateBytes 
    { 
     get 
     {     
      GC.Collect(); 
      GC.WaitForPendingFinalizers(); 
      GC.Collect(); 
      return Process.GetCurrentProcess().PrivateMemorySize64; 
     } 
    } 

我的問題是:爲什麼會在差異巨大的變化? (例如:一次運行11Mo,下一次33Mo)。這些變化是正常的還是我可以刪除它們?

精度:我不是在尋找一個探查器工具! (我已經使用了一個!)

回答

3

您可以嘗試使用外部事件探查器,它們適合您的目的,以查找應用程序中的內存泄漏和瓶頸。依靠垃圾收集器調用和打印值不像使用探查器的準確廣告。有很多.NET可以搜索Google。只是舉一些:

從微軟 official one

他人

Yourkit

MemProfiler

JetBrains

+0

我已經使用了賽特MemProfiler上一個中等規模的應用程序(50萬線),雖然三年前,它的運作非常好。您可以捕捉快照,然後「比較」快照以找出實際發生的變化。 – stusmith 2009-02-10 10:08:11

2

PrivateBytes是進程的內存佔用。對於託管代碼,您只能在託管堆上分配空間。但是,操作系統並不知道託管堆的任何信息。對於Windows應用程序而言,.NET只是另一個過程。

但是,進程本身顯然需要託管堆的內存。即運行時將使用標準OS調用分配內存段。如果可能的話,這些分段將被重新使用,並且在垃圾收集後不一定會被釋放。

0

你會發現內存泄漏本身只在你的P/Invoke代碼中。 .Net中的「新」內存泄漏是死的參考。 .Net中的大部分內存泄漏問題實際上涉及到對不再使用的對象的引用,這意味着它永遠不會被垃圾收集。

要小心線程,我會警惕你達到一個點,你可以可靠地調用你指定的函數,並保證所有的對象現在超出範圍。

2

使用GC.GetTotalMemory()獲取當前在託管堆上分配的估計字節數。

對於真正的內存泄漏檢測,我建議你轉向一個特殊的分析器。