垃圾收集器用來在.NET中進行內存管理,特別是它可以恢復正在進行中的應用程序需要的內存。到目前為止,WINDOWS平台已經使用了兩種技術來釋放進程向系統動態請求的內存:
完全以手工方式使應用程序代碼完成這些工作
讓對象維護引用計數
讓應用程序代碼負責釋放內存是低級、高性能的語言使用的技術,例如C++。這種技術很有效,而且可以讓資源在不需要的時候就釋放(一般情況下),但最大的缺點是頻繁出現錯誤,請求內存的代碼還必須明確通知系統它什麼時候不再需要該內存,但是這很容易被遺漏,從而導致內存洩露。
盡管現代的開發環境提供了幫助檢測內存洩露的工具,但它們很難追蹤錯誤,因為直到內存已經大量洩露從而已經使WINDOWS拒絕為進程提供資源時,它們才會發揮作用。到那個時候,由於對內存的需求,會使整個計算機變的相當緩慢。
維護引用計數是COM對象采用的一種技術,其方法是每個COM組件都保留一個計數,記錄客戶機目前對它的引用數。當這個計數下降到0的時候,組件就會自己刪除自己(侯傑曾經在《程序員》雜志撰寫過自己刪除自己的組件的文章),並釋放相應的內存和資源,它帶來的問題是仍然需要客戶機通知組件它們已經完成了內存的使用。只要有一個客戶機沒有這麼做,對象就仍然駐留在內存中。在某些方面,這是比C++內存洩露更加嚴重的問題,因為COM對象可能存在於它自己的進程中,從來不會被系統刪除(在C++內存洩露問題上系統至少可以在進程中斷時候釋放所有的內存)。
。NET運行庫采用的方法是垃圾收集器,這是一個程序,其目的是清理內存,方法是所有動態請求的內存都分配到堆上(這對所有的語言都一樣,但是在。NET中,CRL維護它自己的托管堆,以供。NET應用程序使用)當。NET檢測到給定進程的托管堆已滿,需要清理時,就調用垃圾收集器。垃圾收集器處理目前代碼中的所有變量檢查對存儲在托管上的對象的引用確定哪些對象可以從代碼中訪問——既哪些對象有引用。沒有引用的對象就不能再從代碼中訪問,因而被刪除。JAVA就使用與此類似的垃圾收集系統。
之所以在。NET中使用垃圾收集器,是因為中間語言已用來處理進程。其規則要求,第一,不能引用已有的對象,除非復制已有的引用。第二,中間語言是類型安全的語言。在這裡,其含義是如果存在對對象的任何引用,該引用中就有足夠的信息來確定對象的類型。
垃圾收集器機制不能和諸如非托管C++的語言一起使用,因為C++允許指針自由地轉換數據類型。
垃圾收集器的一個重要方面是它是不確定的。換而言之不能保證什麼時候會調用垃圾收集器;。NET運行庫決定需要它時就可以調用它(除非明確調用垃圾收集器)。但可以重寫這個過程,在代碼中調用垃圾收集器。