在本章中,我們將介紹垃圾收集的概念,垃圾收集是.NET托管代碼平臺最重要的特性之一。 垃圾收集器(GC)管理內(nèi)存的分配和釋放。 垃圾收集器用作自動內(nèi)存管理器。
- 我們不需要知道如何分配和釋放內(nèi)存或管理使用該內(nèi)存的對象的生命周期
- 每當使用
new關(guān)鍵字聲明對象或?qū)⒅殿愋脱b箱時,都會進行分配。分配通常非常快。 - 當沒有足夠的內(nèi)存分配一個對象時,GC必須收集和處理垃圾內(nèi)存以使內(nèi)存可用于新的分配。
這個過程被稱為垃圾收集。
垃圾收集的優(yōu)勢
垃圾收集提供以下好處(優(yōu)勢) -
- 在開發(fā)應(yīng)用程序時,不需要手動釋放內(nèi)存。
- 它還有效地在托管堆上分配對象。
- 當對象不再使用時,它將通過清除內(nèi)存來回收這些對象,并將內(nèi)存保留為將來的分配。
- 托管對象自動獲得干凈的內(nèi)容,所以它們的構(gòu)造函數(shù)不必初始化每個數(shù)據(jù)字段。
- 它還通過確保對象不能使用其他對象的內(nèi)容來提供內(nèi)存安全性。
垃圾收集的條件
垃圾收集在下列條件之一時發(fā)生:
- 當系統(tǒng)的物理內(nèi)存較低時。
- 托管堆上分配的對象使用的內(nèi)存超過了可接受的閾值。該閾值在流程運行時不斷調(diào)整。
GC.Collect方法被調(diào)用,在幾乎所有情況下,不必調(diào)用此方法,因為垃圾收集器連續(xù)運行。這種方法主要用于獨特的情況和測試。
階段過程
.NET垃圾收集器有3代,每一代都有自己的堆,用于存儲分配的對象。有一個基本的原則,判定大多數(shù)對象是短暫的還是長期的。
1. 第一代(0)
- 在第
0代中,首先分配對象。 - 在這一代,對象通常不會超越第一代,因為在下一次垃圾收集時,它們不再被使用(超出范圍)。
0代很快收集,因為它相關(guān)的堆很小。
2. 第二代(1)
- 在第一代,對象有第二個機會空間。
- 在第
0代收集(通常是基于巧合的時機)下壽命很短的對象會轉(zhuǎn)到第1代。 - 第一代集合也很快,因為它的關(guān)聯(lián)堆也很小。
- 前兩堆仍然很小,因為對象被收集或提升到下一代堆。
3. 第三代(2)
- 在第二代,所有的長對象都是活動的,它的堆可以長得很大。
- 這一代的對象可以長期存活下去,沒有下一代堆積對象可以進一步推廣。
- 垃圾收集器有一個額外的堆,用于稱為大對象堆(LOH)的大型對象。
- 它保留
85,000字節(jié)或更大的對象。 - 大對象并沒有分配到代代堆,而是直接分配給了LOH
- 第二代和LOH收集可能會花費很長時間運行的程序或運行大量數(shù)據(jù)的程序。
- 已知大型服務(wù)器程序在十幾個GB中堆積如山。
- GC采用各種技術(shù)來減少阻止程序執(zhí)行的時間。
- 主要方法是在后臺線程上盡可能多地執(zhí)行垃圾回收工作,而不會干擾程序執(zhí)行。
- GC還為開發(fā)人員提供了一些方法來影響其行為,這對提高性能非常有用。