2009-04-16 102 views
2

我正在運行下面的代碼,結果在發佈模式下運行時完全不同。在調試模式下,它從不收集類A的對象,在Reaelse模式下,它立即收集類A的對象。GC.COllect()似乎無法在調試模式下工作

有人可以解釋爲什麼。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace ConsoleApplication2 { 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      A obj = new A(); 

      B bobj = obj.objB; 

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

      while (bobj.isLive) 
      { 
       Console.WriteLine("Is Alive!!"); 
      } 

      Console.WriteLine("Is Dead!!"); 

      Console.ReadLine(); 
     } 
    } 

    class A:IDisposable 

    { 
     public B objB = new B(); 

     public A() 
     { } 

     ~A() 
     { 
      objB.Dispose(); 
     } 

     #region IDisposable Members 

     public void Dispose() 
     { 
      GC.SuppressFinalize(this); 
     } 

     #endregion 


    } 
    class B:IDisposable 
    { 
     public bool isLive = true; 

     #region IDisposable Members 

     public void Dispose() 
     { 
      this.isLive = false; 
      GC.SuppressFinalize(this); 
     } 

     #endregion 
    } } 

回答

4

在調試模式下,編譯器不優化本地變量。因此,對A的引用仍然存在。在發佈模式下,編譯器優化了使用情況,以便引用被丟棄並且可以收集對象。

+0

這不是原因。這個參考文件並沒有被拋棄,它被認爲是不活躍的,並且這與最優化沒有任何關係。這是另一種方式;該變量可以在該點處於非活動狀態時進行優化。 – Guffa 2009-04-16 12:22:20

+0

「推翻」可能有點太簡單了,因爲解釋,同意。不過,原因是正確的;在釋放模式下沒有強大的參考,阻止GC收集實例。 – Lucero 2009-04-16 12:30:41

2

垃圾收集器在調試模式和發佈模式下處理變量用法有所不同。

在發佈模式下,變量的使用僅限於實際使用的地方。在最後一次使用變量之後,該對象將用於垃圾收集。

在調試模式下,可變參數的使用範圍擴大到它的範圍。這是因爲調試器中的監視窗口可以在整個範圍內顯示變量的值。

3

我剛在我的測試中發現了這種行爲。插入

obj = null; 

在GC.Collect()應該有所幫助。我認爲這是一種「模擬」優化。

相關問題