2011-11-14 34 views
2

在尋找內存泄漏時,我發現了一件奇怪的事情,我不知道它是否正常。這是內存泄漏還是正常行爲?

爲了查找內存泄漏,我創建了一個小的測試應用程序與新的一個按鈕和一個按鈕檢查這樣做:

List<WeakReference> WeakReferences = new List<WeakReference>(); 

private void Button_New(object sender, RoutedEventArgs e) 
{ 
    WeakReferences.Add(new WeakReference(new ObjectUnderTest())); 
    // Adding a bunch of other objects to test here 
} 
private void Button_Check(object sender, RoutedEventArgs e) 
{ 
    GC.Collect(); 
    GC.WaitForPendingFinalizers(); 
    GC.Collect(); 

    int AliveCounter = 0; 
    foreach (var item in WeakReferences) 
    { 
     if (item.IsAlive) 
     { 
      AliveCounter++; 
      Debug.WriteLine("Object " + item.Target.GetType().ToString() + " still alive!"); 
     } 
    } 
    if (AliveCounter > 0) 
    { 
     MessageBox.Show(AliveCounter.ToString() + " objects still alive!"); 
    } 
    else 
    { 
     MessageBox.Show("No objects alive!"); 
    } 
} 

我大部分的測試對象得到正確的垃圾收集在這種情況下,但有是一些仍然活着的物體。

經過更多測試後,我發現這些對象確實被垃圾回收,但只有在單擊檢查按鈕之前切換到另一個應用程序。

你認爲,這是正常的行爲,還是這是一個內存泄漏,我必須解決?

附加信息: 目前我認爲這確實是一個問題,但也許它不會在我們的生產代碼中發生。

  • 添加上新點擊100個對象給出後約650 objetcs內存異常,所以GC不會收集,即使所需的內存用於其他目的。
  • AddMemoryPressure不會使任何更確定性。
  • 使用鼠標點擊切換應用程序並無幫助,只有使用ALT + TAB進行切換纔有用!
  • 有時它有助於在我的測試應用程序中打開一個新窗口。
+3

如果他們最終得到收集,它不能是一個「泄漏」 - 這聽起來更像是「我希望GC更積極」 –

+0

這只是一個測試應用程序,因爲我們有很多泄漏,主要是因爲忘記註銷的事件。在這個測試應用程序中,如果GC更具侵略性,那會更好。但對於我們的真實應用程序,我只想知道我現在是否可以確定,如果需要,可以收集這些對象。我們不想告訴GC何時收集,我們只是想確保它們不會泄漏。 我們真正的應用程序將全天候運行,所以如果它泄漏將是一個問題。 – MTR

回答

5

GC.Collect()在調用時沒有GCCollectionMode參數,那麼GCCollectionMode.Default使用它,在CLR的大多數版本,相同GCCollectionMode.Forced,迫使收集發生。爲確保您強制收集,請嘗試撥打GC.Collect(GCCollectionMode.Forced)

如果你還是找的對象被關押活着,這可能是由於與併發收集你的線程賽車(併發收集是在大多數環境中的默認值)或也許你的ObjectUnderTest類型是自我復活或具有複雜參考路徑混淆了GC的第一遍(一種不太可能的情況,但你永遠不知道)?

在一般說明中,GC將決定何時是收集給定對象的最佳時間,並且此行爲是非確定性的(除非您致電GC.Collect(GCCollectionMode.Forced)或等效)。在某些邊緣情況下,有必要影響垃圾收集器的行爲,但在大多數情況下,最好讓GC做這件事,而不用擔心它的有效性。這通常是足夠高效的,並且使其更有效地操作可能相當困難且涉及。

+2

如果您調用GC.Collect,那麼它是確定性的... GCCollectionMode.Default(通過MSDN)與GCCollectionMode相同。強制,意思是「強制垃圾收集立即發生」。這非常確定。 –

+0

它強制垃圾收集立即發生,但垃圾收集在其選擇中仍然是獨立的。因此,它可以決定暫時不釋放緩衝區。或不?我認爲亞當在這個意義上打算「非確定性」,比如「並不總是做同樣的事情」。 – gd1

+0

我認爲馬克有一個觀點。我編輯了答案。 –