<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          搞懂系列三: G1垃圾收集器

          共 4154字,需瀏覽 9分鐘

           ·

          2022-06-17 19:49

          點擊上方藍色字體,選擇“設為星標”


          回復”學習資料“獲取學習寶典


          一.G1 GC術語


          1.1 并發(fā)

            并發(fā)的意思是Java應用執(zhí)行和垃圾收集活動可以同時進行


          1.2 并行

            并行的意思是垃圾收集運算是多線程執(zhí)行的,比如CMS垃圾收集器的年輕代就是并行的,并行與串行的區(qū)別如下圖,左邊為串行,右邊為并行:


          1.3 STW

            STW(stop the world)意思是在一個垃圾回收事件中,所有Java應用線程會被暫停。只有暫停,應用才不會產(chǎn)生新的垃圾,有益于垃圾收集器更好的標記垃圾對象。(這就像是你在家掃狗毛,肯定要把狗先關籠子,停止它的活動)


          1.4 Region

            請先忘記這個圖,學習G1過程中不會對每個代進行設置了

            G1垃圾收集器利用分而治之的思想將堆進行分區(qū),劃分為一個個的區(qū)域。每次收集的時候,只收集其中幾個區(qū)域,以此來控制垃圾回收產(chǎn)生的STW

            G1和其他GC算法最大的區(qū)別是弱化分代概念,引入分區(qū)思想!!!

            如果要另外選擇分區(qū)的尺寸,可以通過命令行選項:-XX:G1HeapRegionSize=n中進行設置


          1.5 RSet

            G1垃圾收集器里每一個RSet對應的是一個Region內部對象引用情況,說白了就是存在Region中存活對象的指針。在標記存活對象的時候,G1使用RSet概念,將每個分區(qū)指向分區(qū)內的引用記錄在該分區(qū),避免對整個堆掃描,并行獨立處理垃圾集合

          • 老年代對年輕代的引用,維護老年代分區(qū)指向年輕代分區(qū)的指針

          • 老年代對老年代的引用。在這里,老年代中不同分區(qū)的指針將被維護在老年代擁有分區(qū)的RSet中

            如下圖,我們可以看到3個分區(qū),x(年輕代分區(qū))、y和z(老年代分區(qū))。x有一個來自z的對內引用。這個引用記錄在x的RSet中,分區(qū)z有2個對內引用,一個來自x一個來自y,因為年輕代分區(qū)作為一個整體回收的,所以只需記錄來自y的對內引用,不用記錄x的對內引用


          1.6 CSet

            Collection Set,簡稱CSet。在垃圾收集過程中收集的Region集合可以稱為收集集合(CSet),也就是在垃圾收集暫停過程中被回收的目標。GC時在CSet中的所有存活數(shù)據(jù)都會被轉移,分區(qū)釋放回空閑分區(qū)隊列

            見下圖,左邊的年輕代收集CSet代表年輕代的一部分分區(qū),右邊的混合收集CSet代表年輕代的一部分區(qū)和老年代的多個分區(qū):

            


          1.7 PLAB

            Promotion Local Allocation Buffers,對象晉升到survivor分區(qū)或者老年代分區(qū)的過程是在GC線程的晉升本地分配緩沖區(qū)(PLAB)進行的,每個線程有獨立的PLAB。作用是避免多線程競爭相同數(shù)據(jù)。和下面介紹的TLAB思想是一致的


          1.8 TLAB

            Thread Local Allocation Buffers,線程本地分配緩存。JVM使用了TLAB這種線程專屬的區(qū)間來避免多線程沖突(無鎖方式),提高對象分配效率。TLAB本身占用了Eden空間,即JVM會為每一個線程都分配一塊TLAB空間


          1.9 IHOP

            InitiatingHeapOccupancyPercent,簡稱IHOP。缺省情況是Java堆內存的45%。當老年代的空間超過45%,G1會啟動一次混合周期收集

            這也是G1和CMS之間較大的區(qū)別,G1的百分比是相對于整個Java堆而言的,CMS(CMSInitiatingOccupancyFraction)僅僅是針對老年代空間的占比。

            為什么G1如此設計???

            因為G1沒有固定物理上分割一塊內存作為老年代,而是用了Region的思想,這些Region可能是eden,survivor、老年代或者巨型分區(qū),所以獲取針對老年代本身的占用百分比沒有意義


          2.10 巨型分區(qū)

            巨型對象會以連續(xù)分區(qū)的形式來存放,這種就叫巨型分區(qū)。巨型對象無法利用年輕代里的TLAB和PLAB。在JDK 8u40之前,它只能在并發(fā)收集周期的清除階段回收,但是在JDK 8u40之后,巨型分區(qū)可以在年輕代收集中和full GC被回收


          二.G1的設計


          2.1 為什么會有G1?

            為什么會有G1呢?因為并發(fā)、并行和CMS垃圾收集器都有2個共同的問題:

          1. 老年代收集器大部分操作都必須掃描整個老年代空間(標記,清除和壓縮)。這就導致了GC隨著Java堆空間而線性增加或減少

          2. 年輕代和老年代是獨立的連續(xù)內存塊,所以要先決定年輕代和年老代放在虛擬地址空間的位置


          2.2 Region的設計

            上面說到,G1垃圾收集器利用分而治之的思想將堆進行分區(qū),劃分為一個個的區(qū)域。G1垃圾收集器將堆拆成一系列的分區(qū),這樣的話,大部分的垃圾收集操作就只在一個分區(qū)內執(zhí)行,而不是整個堆或者整個代


          2.3 設計目標

            G1的設計目標就是把必要的調整限定在以下2個:

          1. 設置最大的Java堆空間

          2. 設置指定GC暫停時間

            G1會通過調整Java堆尺寸大小來滿足設定的暫停時間目標,暫停時間目標越短,年輕代空間越小,老年代空間相對越大


          2.4 使用場景  

            G1 GC切分堆內存為多個區(qū)間(Region),從而避免很多GC操作在整個Java堆或者整個年輕代進行。G1 GC只關注你有沒有存貨對象,都會被回收并放入可用的Region隊列。G1 GC是基于Region的GC,適用于大內存機器。即使內存很大,Region掃描,性能還是很高的

            如果現(xiàn)在采用的收集器沒有問題,就不要選擇G1,如果追求低停頓,那么G1已經(jīng)是一個可嘗試的選擇,如果追求吞吐量,就不要選G1了


          四.G1的垃圾回收

            G1的垃圾收集周期主要有4種類型:年輕代收集周期、多級并發(fā)標記周期、混合收集周期和full GC(轉移失敗的安全保護機制)

            這一節(jié)我會以應用啟動的時間順序來講,這樣比較易懂一點,也可以參照G1垃圾收集活動時序圖:


          4.1 年輕代收集

            應用剛啟動,慢慢流量進來,開始生成對象。G1會選一個分區(qū)并指定他為eden分區(qū),當這塊分區(qū)用滿了之后,G1會選一個新的分區(qū)作為eden分區(qū),這個操作會一直進行下去直到達到eden分區(qū)上限,也就是說eden分區(qū)已經(jīng)被占滿,那么會觸發(fā)一次年輕代收集

            年輕代收集首先做的就是遷移存活對象,它使用單eden,雙survivor進行復制算法,它將存活的對象從eden分區(qū)轉移到survivor分區(qū),survivor分區(qū)內的某些對象達到了任期閾值之后,會晉升到老年代分區(qū)中。原有的年輕代分區(qū)會被整個回收掉

            同時,年輕代收集還負責維護對象年齡,存活對象經(jīng)歷過年輕代收集總次數(shù)等信息。G1將晉升對象的尺寸總和和它們的年齡信息維護到年齡表中,結合年齡表、survivor占比(--XX:TargetSurvivorRatio 缺省50%)、最大任期閾值(--XX:MaxTenuringThreshold 缺省為15)來計算出一個合適的任期閾值

            調優(yōu):我們可以通過--XX:MaxGCPauseMillis,調優(yōu)年輕代收集,縮小暫停時間


          4.2 并發(fā)標記周期

            隨著時間推移,越來越多的對象晉升到老年代中,當老年代占比(相對于Java總堆而言)達到IHOP參數(shù)(上圖的IHOP Trigger)之后,那么G1首先會觸發(fā)并發(fā)標記周期(上圖的Concurrent Marking Cycle),當完成后才會開始下一小節(jié)的混合垃圾收集周期  

            G1的并發(fā)標記循環(huán)分5個階段:

            第一階段:初始標記(上圖Young Collection with Initial Mark),收集所有GC根(對象的起源指針,根引用),STW,在年輕代完成

            第二階段:根區(qū)間掃描,標記所有幸存者區(qū)間的對象引用

            第三階段:并發(fā)標記(上圖Concurrent Marking),標記存活對象

            第四階段:重新標記(上圖Remark),是最后一個標記階段,STW,很短,完成所有標記工作

            第五階段:清除(上圖Clean),回收沒有存活對象的Region并加入可用Region隊列

            調優(yōu):我們可以通過--XX:InitiatingHeapOccupancyPercent,配置適合應用的IHOP值(過大會可能轉移失敗,過小可能過早引起并發(fā)標記周期)

                 我們也可以通過--XX:ConcGCThreads,增加并發(fā)線程數(shù)


          4.3 混合收集周期

            當達到IHOP參數(shù)并完成上一小節(jié)的并發(fā)標記周期之后,混合收集周期就啟動了,一個周期里的單次STW的混合收集和年輕代收集是類似的,唯一區(qū)別就是在混合收集過程中會包含一部分老年分區(qū),所以也叫混合收集

            看上圖的Mixed Collection Cycle,中間有好幾段Mixed Collection,說明混合收集周期包含多次收集次數(shù)。那么什么影響收集次數(shù)呢?是固定的?還是?有兩個參數(shù)比較重要:

            -XX:G1MixedGCCountTarget:缺省值為8,意思是能啟動混合收集的數(shù)目設定一個物理限制。G1根據(jù)將回收的老年分區(qū)除以該參數(shù)值得到每次混合收集的老年代CSet最小數(shù)量

            -XX:G1HeapWastePercent:缺省值為5%,每次混合收集暫停,G1算出廢物百分比,根據(jù)堆廢物百分比,當收集達到參數(shù)時,不再啟動新的混合收集

            調優(yōu):當暫停時間和運行時間呈現(xiàn)指數(shù)級增長,可以通過-XX:G1HeapWastePercent,調高該參數(shù)會有所幫助,但這也導致更多碎片化


          4.4 full GC

            有2個條件同時滿足則會觸發(fā)full GC

            1.拷貝存活對象晉升(promotion)失敗,無法找到可用的空閑分區(qū),GC日志記錄為to-space exhausted。或者分配巨型對象無法在老年代找到連續(xù)足夠的分區(qū)

            2.當發(fā)生第一個條件后,G1會嘗試增加堆使用量,如果擴展失敗,那么會觸發(fā)安全措施機制同時發(fā)生full GC

            full GC中,單個線程會對整個堆的所有代中所有分區(qū)做標記、清除以及壓縮動作!!非常非常昂貴的操作!


          -------------  END  -------------
          掃描下方二維碼,加入技術群。暗號:加群


          瀏覽 27
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  中文天堂在线中文 | 91精品少妇一区二区三区蜜桃臀 | 黄色免费性爱视频 | 国产精品久久久久久久久动漫 | 在线观看免费观看在线黄色 |