一、什么是GC
GC是垃圾回收(Garbage Collector)的縮寫。GC可以說是.NET眾多機制中最為重要的,對程序員代碼書寫方式影響最大的機制。在CLR規范制定之初,所有機制都還在斟酌的時候,垃圾回收已經被確定會存在於.NET框架之中。
.NET的程序大部分被稱為被托管的代碼。托管的意義很廣泛,其中重要的一點就是代碼中對象內存的分配和釋放是由.NET內存管理和垃圾回收機制統一管理的。和傳統C++的程序員不同,C#或者其他面向.NET框架語言的程序員不再需要時刻警惕內存的泄露,因為托管對象的內存最終會被垃圾回收釋放掉,盡管不同的編寫方式會產生不同的運行效率。
這里指的是受托管的對象,當使用了一些非托管的資源時,程序員仍然需要手動地釋放它們。
所謂的垃圾回收,是指.NET清理托管堆上不會再被使用的對象內存,並且移動仍在被使用的對象,使它們緊靠托管堆的一邊。下圖展示了一次垃圾回收后托管堆上的變化。
如上圖所示,GC的執行過程分為兩個基本動作:
- 找到所有不再被使用的對象:對象A和對象C,並標記為垃圾。
- 移動扔在被使用的對象:對象B和對象D。這樣對象A和對象C的內存空間就被騰空出來了,以備下次分配的時候使用。
這里簡化了GC的執行過程,省略了包含Finalize方法對象的處理,以及大對象分配的特殊性。
垃圾回收由.NET垃圾回收機制來控制,理論上當托管堆內存不夠時,.NET會運行垃圾回收來得到更多的可分配內存,微軟並沒有公開這一部分的算法,程序員無法精確得知垃圾回收的執行時間。在通常情況下,程序員不需要干涉垃圾回收的執行。不過CLR仍然提供了一個手動執行垃圾回收的方法:GC.Collect()方法。當程序員需要在某一批對象不再使用並且及時釋放內存時,可以調用該方法來實現。
垃圾回收涉及了對象塊的移動、遍歷找到不被使用的對象,這是一個相當耗費資源的過程。所有的程序優化策略都會有一條:盡量減少垃圾回收的負擔和次數。在編寫程序的過程中,應該注意避免不必要的資源分配,因為這意味着多余的垃圾回收的負擔。
二、總結
垃圾回收是指收集釋放托管堆上不再被使用的內存對象。其過程基本包括:通過算法找到不再被使用的對象、移動對象使所有扔被使用的對象緊靠托管堆的一邊和調整各個狀態變量。
垃圾回收的運行成本較高,對性能的影響較大。程序員在編寫.NET代碼時,應該避免不必要的內存分配,盡量減少或避免使用GC.Collect來執行垃圾回收。