G1混合式GC與三色標記算法詳解【純理論】


繼續基於上一次https://www.cnblogs.com/webor2006/p/11146273.html的理論進一步了解G1。

G1收集概覽:

G1算法將堆划分為若干個區域(Region),它仍然屬於分代收集器。不過,這些區域的一部分包含新生代,新生代的垃圾收集依然采用暫停所有應用線程的方式,將存活對象拷貝到老年代或者Survivor空間。老年代也分成很多區域,G1收集器通過將對象從一個區域復制到另外一個區域,完成了清理工作。這就意味着,在正常的處理過程中,G1完成了堆的壓縮(至少是部分堆的壓縮),這樣也就不會有CMS內存碎片問題的存在了

Humongous區域:

在G1中,還有一種特殊的區域,叫Humongous區域。如果一個對象占用的空間達到或者超過了分區容量50%以上,G1收集器就認為這是一個巨型對象。這些巨型對象,默認直接會被分配在老年代,但是如果它是一個短期存在的巨型對象,就會對垃圾收集器造成負面影響。為了解決這個問題,G1划分了一個Humongous區,它用來專門存放巨型對象。如果一個H區裝不下一個巨型對象,那么G1會尋找連續的H分區來存儲。為了能找到連續的H區,有時候不得不啟動Full GC

G1 Young GC:

  • Young GC主要是對Eden區進行GC,它在Eden空間耗盡時會被觸發。在這種情況下,Eden空間的數據移動到Survivor空間中,如果Survivor空間不夠,Eden空間的部分數據會直接晉升到老年代空間。Survivor區的數據移動到新的Survivor區中,也有部分數據晉升到老年代空間中最終Eden空間的數據為空,GC完成工作,應用線程繼續執行。
  • 如果僅僅GC新生代對象,我們如何找到所有的根對象呢?老年代的所有對象都是根么?那這樣掃描下來會耗費大量的時間。於是,G1引進了RSet的概念。它的全稱是Remembered Set,作用是跟蹤指向某個heap區內的對象引用。下面看圖:
  • 在CMS中,也有RSet的概念,在老年代中有一塊區域用來記錄指向新生代的引用。這是一種point-out,在進行Young GC時,掃描根時,僅僅需要掃描這一塊區域,而不需要掃描整個老年代。 

  • 但在G1中,並沒有使用point-out,這是由於一個分區太小,分區數量太多,如果是用point-out的話,會造成大量的掃描浪費,有些根本不需要GC的分區引用也掃描了。
  • 於是G1中使用point-in來解決。point-in的意思是哪些分區引用了當前分區中的對象。這樣,僅僅將這些對象當做根來掃描就避免了無效的掃描。
  • 由於新生代有多個,那么我們需要在新生代之間記錄引用嗎?這是不必要的,原因在於每次GC時,所有新生代都會被掃描,所以只需要記錄老年代到新生代之間的引用既可
  • 需要注意的是,如果引用的對象很多,賦值器需要對每個引用做處理,賦值器開銷會很大,為了解決賦值器開銷這個問題,在G1中又引入了另外一個概念,卡表(Card Table)。一個Card Table將一個分區在邏輯上划分為固定大小的連續區域,每個區域稱之為卡。卡通常較小,介於128到512字節之間。Card Table通常為字節數組,由Card的索引(既數組下標)來標識每個分區的空間地址。
  • 默認情況下,每個卡都未被引用。當一個地址空間被引用時,這個地址空間對應的數組索引的值被標記為“0”,既標記為被引用,此外RSet也將這個數組下標記錄下來。一般情況下,這個RSet其實是一個Hash Table,key是別的Region的起始地址,Value是一個集合,里面的元素是Card Table的Index。

另外它分為下幾個階段:

  • 階段1:根掃描
    表態和本地對象被掃描
  • 階段2:更新RS
    處理dirty card隊列更新RS
  • 階段3:處理RS
    檢測從年輕代指向老年代的對象
  • 階段4:對象拷貝
    拷貝存活的對象到survivor/old區域
  • 階段5:處理引用隊列
    軟引用、弱引用、虛引用處理

再談Mixed GC:

  • Mixed GC不僅進行正常的新生代垃圾收集,同時也回收部分后台掃描線程標記的老年代分區。
  • 這的GC步驟分為兩步:
    1、全局並發標記(global concurrent marking)
    2、拷貝存活對象(evacuation)
  • 在G1 GC中,global concurrent marking主要是為Mixed GC提供標記服務的,並不是一次GC過程的一個必須環節。global concurrent marking的執行過程分為四個步驟,這個在之前已經學習過了,回憶一下:

三色標記算法:

  • 提到並發標記,我們不得不了解並發標記的三色標記算法。它是描述追蹤式回收器的一種有效的方法,利用它可以推演回收器的正確性。 
  • 我們將對象分成三種類型:
    1、黑色:根對象,或者該對象與它的子對象都被掃描過(對象被標記了,且它的所有field也被標記完了)。
    2、灰色:對象本身被掃描,但還沒掃描完該對象中的子對象(它的field還沒有被標記或標記完)。
    3、白色:未被掃描對象,掃描完成所有對象之后,最終為白色的為不可達對象,既垃圾對象(對象沒有被標記到)。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM