在本章中,我們將介紹垃圾收集的概念,垃圾收集是.NET受控代碼平台最重要的特性之一。 垃圾收集器(GC)管理記憶體的分配和釋放。 垃圾收集器用作自動記憶體管理器。
- 我們不需要知道如何分配和釋放記憶體或管理使用該記憶體的物件的生命週期
- 每當使用
new
關鍵字宣告物件或將值型別裝箱時,都會進行分配。分配通常非常快。 - 當沒有足夠的記憶體分配一個物件時,GC必須收集和處理垃圾記憶體以使記憶體可用於新的分配。
這個過程被稱為垃圾收集。
垃圾收集的優勢
垃圾收集提供以下好處(優勢) -
- 在開發應用程式時,不需要手動釋放記憶體。
- 它還有效地在託管堆上分配物件。
- 當物件不再使用時,它將通過清除記憶體來回收這些物件,並將記憶體保留為將來的分配。
- 託管物件自動獲得乾淨的內容,所以它們的建構函式不必初始化每個資料欄位。
- 它還通過確保物件不能使用其他物件的內容來提供記憶體安全性。
垃圾收集的條件
垃圾收集在下列條件之一時發生:
- 當系統的實體記憶體較低時。
- 託管堆上分配的物件使用的記憶體超過了可接受的閾值。該閾值在流程執行時不斷調整。
GC.Collect
方法被呼叫,在幾乎所有情況下,不必呼叫此方法,因為垃圾收集器連續執行。這種方法主要用於獨特的情況和測試。
階段過程
.NET垃圾收集器有3
代,每一代都有自己的堆,用於儲存分配的物件。有一個基本的原則,判定大多數物件是短暫的還是長期的。
1. 第一代(0)
- 在第
0
代中,首先分配物件。 - 在這一代,物件通常不會超越第一代,因為在下一次垃圾收集時,它們不再被使用(超出範圍)。
0
代很快收集,因為它相關的堆很小。
2. 第二代(1)
- 在第一代,物件有第二個機會空間。
- 在第
0
代收集(通常是基於巧合的時機)下壽命很短的物件會轉到第1
代。 - 第一代集合也很快,因為它的關聯堆也很小。
- 前兩堆仍然很小,因為物件被收集或提升到下一代堆。
3. 第三代(2)
- 在第二代,所有的長物件都是活動的,它的堆可以長得很大。
- 這一代的物件可以長期存活下去,沒有下一代堆積物件可以進一步推廣。
- 垃圾收集器有一個額外的堆,用於稱為大物件堆(LOH)的大型物件。
- 它保留
85,000字
節或更大的物件。 - 大物件並沒有分配到代代堆,而是直接分配給了LOH
- 第二代和LOH收集可能會花費很長時間執行的程式或執行大量資料的程式。
- 已知大型伺服器程式在十幾個GB中堆積如山。
- GC採用各種技術來減少阻止程式執行的時間。
- 主要方法是在後台執行緒上盡可能多地執行垃圾回收工作,而不會干擾程式執行。
- GC還為開發人員提供了一些方法來影響其行為,這對提高效能非常有用。