1,什麼是垃圾Garbage?
每一個應用程序都有一組根root。根可以用來標志存儲位置,這些位置指向托管堆中的對象或者被設為null的對象,稱為活動根,並形成一個活動根列表。JIT編譯器和CLR維護著活動根列表,列表能夠被垃圾收集器算法訪問。這樣,垃圾被定義為從活動根列表中不能訪問的堆上對象。
2,垃圾是怎麼回收的?
當垃圾收集器開始運行的時候,它假設堆中的對象都是垃圾,換而言之,它假設應用程序中沒有任何根指向堆中的對象。GC開始遍歷根列表,並建立一個所有從根可以到達的對象圖。例如,GC可能會定位指向堆中對象的全局變量,然後遞歸遍歷所有可到達的對象。當這部分對象圖遍歷完成時,GC將檢查下一個根並遍歷其中的對象。
垃圾回收器的遍歷:一、GC對任一組對象只編譯一次,提高性能;二、如果存在對象循環鏈表,則可避免無限循環。
3,垃圾回收器的性能
垃圾回收的性能取決於:一、托管堆的大小;二、垃圾的多少;三、托管堆中對象是否定義了finalize()方法。(對可回收對象調用finalize方法會減緩垃圾回收的速度)
另一個瓶頸是堆中的大對象。如果C盤結構最為一棵樹保留在內存中,當另一個程序在執行過程中連續的引用這棵樹,這時候這棵樹持續被保留在堆中而永遠不會被作為垃圾回收。處理這樣的大對象時,最好的辦法是:垃圾回收和應用程序訪問同時進行。這種方法通過弱引用(weak reference)實現的,該機制基於對訪問和垃圾回收時機的選擇!一方面,如果對象只是存在弱引用,而且GC正在運行,則該對象會被回收。隨後如果有程序訪問這個對象,訪問會失敗。另一方面,要訪問弱引用的對象,應用程序就必須獲得該對象的一個強引用,那麼由於該對象存在強引用,GC就不能回收該對象。
還有,GC分代回收或者只壓縮部分堆來提高性能。GC分代回收建立在三個假設之上:越是新的對象生命周期越短;越是老的對象生命周期越長;新的對象之間有更強的關聯性並經常被訪問。
注意:GC算法不是一成不變的,為了保證性能的最優化,它是CLR中調整的較為頻繁的一部分。