簡體   English   中英

C# 垃圾收集

[英]C# Garbage collection

假設我們有:

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

垃圾收集器如何處理第一個堆對象? 是否在新分配之前立即進行垃圾回收? 一般機制是什么?

垃圾收集器如何處理第一個堆對象?

誰知道? 這不是確定性的。 想想看這樣的:用無限的內存的系統上,垃圾回收器不會任何事情 您可能認為這是一個不好的例子,但這就是垃圾收集器為您模擬的:一個具有無限內存的系統。 因為在可用內存多於程序所需內存的系統上,垃圾收集器永遠不必運行。 因此,您的程序無法對何時(如果有的話)收集內存做出任何假設。

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

是否在新分配之前立即進行垃圾回收?

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

事實上,它不太可能被收集得如此之快(這會使收集發生得太頻繁)。 此外,在具有足夠內存的系統上,垃圾收集器永遠不必運行。

一般機制是什么?

這是一個相當廣泛的問題。 但其基本原理非常簡單:垃圾收集器模擬了一台具有無限內存的機器。 為此,它會以某種方式跟蹤內存並能夠確定內存何時是垃圾。 當它認為合適時,由於需要模擬無限內存,它會不時收集這些垃圾並使其再次可供分配。

不,沒有任何內容表明該對象會立即被收集。 事實上,這是不太可能的。 垃圾收集器最終會收集它,但您無法確切知道何時。

您可以通過調用GC.Collect強制收集,盡管通常不建議這樣做。

垃圾收集的確切工作原理是一個相當大的主題,但您可以在 MSDN 上閱讀大量文檔。

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

.NET 有一個所謂的“分代”垃圾收集器,我認為它的行為與我自己的行為非常相似。 在幾天的時間里,我讓臟衣服和郵件(“C# 對象”)堆積在我客廳的地板上(“內存”),當我發現我再也看不到地毯時(“內存已滿”) )我花了一些時間清理(“垃圾收集”)起居室(“第 0 代”),扔掉不再需要的物品(“不再可及”),並將剩余的物品移到我的卧室( “第 1 代”)。 很多時候,這為我贏得了一些時間,我不需要再做任何工作了。 但是當我的卧室填滿時,我會做類似的事情,扔掉一些物品並將其他物品移到我的地下室(“第 2 代”)。 有時甚至地下室都填滿了,然后我遇到了真正的問題,需要做一些主要的春季大掃除(“全面收集”)。

將這個比喻應用到您的示例中,我們可能會猜測第一塊垃圾(“堆對象”)就在附近,直到我有時間撿起它(“運行第 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();
    }
}

為了強制垃圾收集器更快地釋放這些對象,您可以將一個字段作為長數組添加到它們中,例如private int []memory; 並在構造函數中: memory=new int[10000000]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM