JVM學習筆記——垃圾回收篇( 六 )

  • -XX:MaxGCPauseMillis=time設置最大的G1垃圾回收時間
  • G1垃圾回收器階段簡介我們通過一張圖來簡單介紹G1垃圾回收器的過程:
    JVM學習筆記——垃圾回收篇

    文章插圖
    我們可以看到整個流程分為三個階段:
    • YoungCollection:新生代階段
    • YoungCollection+ConcurrentMark:新生代階段+并發標記階段
    • MixedCollection:混合收集階段
    Young Collection我們首先給出該階段的展示圖:
    JVM學習筆記——垃圾回收篇

    文章插圖
    我們對其進行解釋:
    • E就是伊甸園,S就是幸存區,O就是老年代
    • 其產生的正常流程就和分代垃圾回收機制一樣,但這階段不會產生GC
    Young Collection + CM我們首先給出該階段的展示圖:
    JVM學習筆記——垃圾回收篇

    文章插圖
    我們對其進行解釋:
    • 其字符含義完全相同
    • 當新生代內存占滿后進行Young GC時會同時進行GC Root的初始標記
    • 老年代占用堆空間比例達到閾值時,進行并發標記(不會產生STW),閾值可以控制
    我們給出并發標記閾值控制語句:
    // 閾值控制-XX:InitiatingHeapOccupancyPercent=percent (默認45%)Mixed Collection我們首先給出該階段的展示圖:
    JVM學習筆記——垃圾回收篇

    文章插圖
    我們對其進行解釋:
    • 其字符含義完全相同
    • 但該階段會對E , S,O進行全面垃圾回收
    • 其中最終標記(Remark)和拷貝存活(Evacation)都會STW(我們均會在后面解釋)
    我們需要注意一點:
    • Mixed Collection可能并不會將所有老年代的數據都刪除
    • 它會根據你設置的最大暫停時間來進行抉擇,如果時間不足以刪除所有老年代數據,就會挑選部分較大的內存數據進行回收
    Full GC我們需要重新總結一下Full GC操作:
    1. SerialGC(串行垃圾回收)
    • 新生代內存不足時發生的垃圾收集 - minor gc
    • 老年代內存不足時發生的垃圾收集 - full gc
    1. ParalllelGC(吞吐量優先垃圾回收)
    • 新生代內存不足時發生的垃圾收集 - minor gc
    • 老年代內存不足時發生的垃圾收集 - full gc
    1. CMS(響應時間優先垃圾回收)
    • 新生代內存不足時發生的垃圾收集 - minor gc
    • 老年代內存不足時優先進行標記操作同步垃圾回收,當內存完全占滿后才采用full gc
    1. G1(Garbage First)
    • 新生代內存不足時發生的垃圾收集 - minor gc
    • 老年代內存不足時優先進行MixedCollection同步垃圾回收,當內存完全占滿后才采用full gc
    G1知識點補充我們在前面已經提到了我們將堆劃分為多個Region
    但其實這個Region并不僅僅只分為了E,S,O三個空間,此外還包括以下空間:
    1. RSet(Remember Set :記憶集合)
    /*每一個Region都會劃出一部分內存用來儲存記錄其他Region對當前持有Rset Region中Card的引用針對G1的垃圾回收時間設置較短,在進行標記過程中可能會導致時間過長,所以我們設置了RSet來儲存部分信息我們可以直接通過掃描每塊Region里面的RSet來分析垃圾比例最高的Region區,放入CSet中,進行回收 。*/
    1. CSet(Collection Set 回收集合)
    /*收集集合代表每次GC暫停時回收的一系列目標分區 。在任意一次收集暫停中,CSet所有分區都會被釋放,內部存活的對象都會被轉移到分配的空閑分區中 。年輕代收集CSet只容納年輕代分區,而混合收集會通過啟發式算法,在老年代候選回收分區中,篩選出回收收益最高的分區添加到CSet中 。*/新生代跨代引用由于我們的初次標記時會去尋找Root部分
    但其實大部分的Root都放入了老年代,但老年底數據較多難以查找,所以G1提供了一種方法:
    • 將老年代O再次劃分為多個區間,名為卡
    • 如果該卡中存儲了Root部分,那么就將該卡標記為臟卡,同時放于RSet中存儲起來便于查找
    我們給出簡單圖示:
    JVM學習筆記——垃圾回收篇

    文章插圖
    同時如果該Root地址發生變化,G1給出了另外的方法進行更換:
    • 在引用變更時通過post-write barrier + dirty card queue
    • concurrent refinement threads 更新 Remembered Set
    Remark重新標記我們在進行標記時通常采用三色標記法:
    JVM學習筆記——垃圾回收篇

    推薦閱讀