2011-10-01 226 views
3

說,我們有:C#垃圾收集

public void foo() 
{ 
    someRefType test = new someRefType(); 
    test = new someRefType(); 
} 

是什麼垃圾收集器做的第一個堆對象?是否在新任務之前立即收集垃圾?什麼是一般機制?謝謝,Juergen

+5

你試過這個(http://www.google.com/search?q=how+c%23+garbage+collection+works)嗎?真的,這將給你一個列表頂部的一堆高質量的解釋。 –

回答

13

垃圾收集器對第一個堆對象做什麼?

誰知道?這不是確定性的。想想這樣吧:在一個有無限內存的系統上,垃圾收集器沒有什麼東西。你可能認爲這是一個不好的例子,但這正是垃圾收集器爲你模擬的:一個具有無限內存的系統。因爲在系統中有足夠多的可用內存而不是程序所需的內存,垃圾收集器從不需要運行。因此,您的程序無法對內存何時(如果曾經)進行收集的任何假設。

所以,你的問題的答案是:我們不知道。

立即在新作業之前收集垃圾嗎?

不。垃圾收集器不確定。你不知道什麼時候會收集和釋放垃圾。您不能對垃圾收集時間或終結器運行時間做出任何假設。

事實上,它收集得太快的可能性不大(這會使收集過於頻繁)。此外,在具有足夠內存的系統上,必須運行垃圾收集器永不

什麼是一般機制?

這是一個相當廣泛的問題。但基本原理非常簡單:垃圾收集器模擬具有無限內存的機器。爲此,它以某種方式記錄內存,並能夠確定內存何時是垃圾。當它看起來合適時,由於它需要模擬無限的內存,它會不時收集這些垃圾並將其重新分配。

+0

或者更確切地說,「我們無法知道」。 –

4

不,沒有什麼說這個對象被立即收集。事實上,這是不太可能的。它將最終由垃圾收集器收集,但您無法確切地知道何時。

您可以通過調用CG.Collect來強制收集,但通常不建議這樣做。

垃圾收集的工作方式是一個相當大的主題,但有很好的文檔,你可以read on MSDN

0

垃圾收集有許多不同的策略,多年來它們變得更加複雜和高效。在文獻和網絡上有很多關於它們的優秀資源。但是我也發現有時一個不完美和豐富多彩的比喻給了我一個直覺,幫助我開始。所以請允許我嘗試:

。NET有一個所謂的「世代」垃圾回收器,我認爲它的表現很像我自己。在幾天的時間裏,我讓髒衣服和郵件(「C#對象」)堆積在我的客廳地板(「內存」)上,當我發現我再也看不到地毯時(「內存已滿」 )我花了一些時間清理(「垃圾收集」)客廳(「0代」),扔掉不再需要的物品(「不再可及」)並將其餘物品移動到我的臥室( 「第1代」)。通常這會給我帶來一些時間,我不需要再做任何工作。但是當我的臥室填滿時,我做了類似的事情,扔掉一些物體並將其他物體移動到我的地下室(「第二代」)。偶爾甚至地下室填滿,然後我有我真正的問題,需要做一些重大的春季大掃除(「全面收集」)。

把這個隱喻應用到你的例子中,我們可能會猜測第一塊垃圾(「堆對象」)只是坐在那裏,直到我開始撿起它(「運行第0代收集器」),當我感覺就像它,當地板完全覆蓋,或者可能永遠不會:-)

0

要查看對象何時被刪除,您可以覆蓋類中的finalize方法以打印何時以及何時刪除對象,如在下面的示例中:

class MyClass 
{ 
    private int _id; 

    public MyClass(int id) 
    { 
     _id = id; 
    } 

    ~MyClass() 
    { 
     Console.WriteLine("Object " + _id + " deleted at " + DateTime.Now + " ."); 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     MyClass p1 = new MyClass(1); 
     p1 = new MyClass(2); 

     Console.ReadKey(); 
    } 
} 

要強制垃圾收集器更快地釋放此對象,您可以dd一個字段作爲一個長陣列,如private int []memory;和構造函數:memory=new int[10000000]