三色標記法與讀寫屏障, G1工作過程


https://www.jianshu.com/p/12544c0ad5c1

https://www.cnblogs.com/GrimMjx/p/12234564.html

自我總結和記憶:

為了解決 三色標記算法 在並發情況下 出現漏標, 多標情況, CMS采用的是 : 寫屏障+增量更新 G1采用的是: 寫屏障+ snapshot at the begining (SATB)

多標----> 浮動垃圾
本輪GC不會回收,只能等下次GC時候回收

對象成員變量引用發生變化,肯定會經歷這三步,
第一步: var G = objE.fieldG; //讀
第二步: objE.fieldG = null; // 寫
第三步: objD.fieldG = G; // 寫

漏標的解決方案: 不同垃圾收集器策略不同
G1 : 這是針對第二步, SATB(snapshot at the beginning)+利用讀寫屏障: SATB,就是gcRoots開始時候的快照,gc根對象在掃描完成時候, 就已經確定好了引用對象鏈, 標記的過程就按照這個 引用對象鏈,進行標記, 如果某一個對象的成員屬性引用發生變化時, 將舊的值保存下來到一個集合中, 並發標記往下taching的時候,仍然將集合中的對象,從白色集合中取出,存到灰色集合中

CMS: 這是針對第三步, 增量更新+寫屏障: 這不要求保留原始快照, 如果某個對象的成員屬性,新增了一個引用, 將這個引用保存到集合中, 並發標記期間,將這個集合中的對象, 從白色集合中取出存到灰色集合中,

jdk11的垃圾收集器: ZGC: 是針對第一步, 讀屏障: 當讀取成員變量時候,就將他保存到集合中, 並發標記期間,將集合中的對象,從白色集合中取出,存到灰色集合中, 這種很保守,很安全,

Serial收集器 (串行) : 特點: 針對新生代, 復制算法, 單線程收集, 進行垃圾收集的時候,必須暫停所有工作線程,直到完成 : 參數設置: -XX:+UseSerialGC, 通常和SerialOld(老年代收集器)組合

ParNew收集器 這個收集器是Serial收集器的多線程版本, 特點: 除了多線程外,其余行為, 特點和Serial收集器一樣, 通常和 CMS(老年代收集器) 組合 參數設置: -XX:+UseParNewGC (強制指定使用ParNew) , -XX:+UseConcMarkSweepGC (指定使用cms后,會默認使用ParNew作為新生代收集器) , -XX:ParallelGCThreads (指定垃圾收集的線程數量, ParNew默認開啟的收集線程與CPU的數量相同)

Parallel Scavenge收集器, (吞吐量收集器) 特點: 新生代收集器, 復制算法, 多線程收集, 他的關注點是:CMS等收集器關注點是盡可能縮短垃圾收集時用戶線程的停頓時間, Parallel Scavenge收集器關注的是一個可控制的吞吐量

老年代:
Serial Old 老年代收集器, 標記整理算法, 標記壓縮算法, 單線程收集 , 作為CMS收集器的后備預案, 當CMS收集器異常時候,它來執行垃圾收集

Parallel Old收集器, 他是Parallel Scavenge收集器的老年代版本, 針對老年代, 標記整理算法, 多線程收集 設置參數: -XX:+UseParallelOldGC

CMS 收集器,並發標記清理, 特點: 針對老年代, 基於標記-清除算法,(不進行壓縮,會產生內存碎片) , 以獲取最短回收停頓時間為目標, 並發收集, 低停頓, 需要更多的內存, 垃圾收集線程和用戶線程同時工作, 參數設置: -XX:+UseConcMarkSweepGC, CMS運作過程:
1)- 初始標記: 僅標記一下 GC Roots能直接關聯到的對象, 速度快, 需要STW
2)- 並發標記: 進行GC Roots 可達性對象的過程, 剛才產生的集合中標記出存活對象, 工作線程也在運行, 並不能保證可以標記出所有的存活對象
3)- 重新標記: 為了修正並發標記期間因工作線程繼續運作,而導致標記變動的那一部分對象的標記記錄, 需要 STW, 且停頓時間比初始標記稍長, 但遠比並發標記短, 采用多線程並行執行來提升效率
4)- 並發清除, 回收所有的垃圾對象, 此時工作線程也會工作,會產生浮動垃圾
可以看到,整個過程,只是標記,清除, 所以會產生內存碎片, 耗時最長的並發標記, 並發清除都可以合工作線程一起工作,

缺點: 浮動垃圾, 如果CMS預留內存空間無法滿足程序需要, 會出現 Concurrent Mode Failure 失敗,此時,臨時啟用 Serial Old收集器,而導致fullGC, 這樣代價很大
解決方法: -XX:+UseCMSCompactAtFullCollection : 作用: CMS出現上面的情況時,不進行FullGC, 而開啟內存碎片的合並整理過程, 但合並整理過程無法並發, 停頓時間變長
-XX:+CMSFullGCsBeforeCompaction: 作用: 設置執行多少次不壓縮的FullGC后,來一個壓縮整理, 為減少合並整理過程的停頓時間,默認為0, 即每次都執行fullGC,不會進行壓縮整理

Parallel Old 收集器(老年代) 多線程, 標記-整理算法

G1收集器, 之前介紹的垃圾收集器,都是將堆分為 新生代,surivivor, 老年代, 分代組合不同的垃圾收集器來收集垃圾. G1收集器,采用分而治之的思想,將堆分為一個一個region區域,(最小為1M), 這些region區域,分為四類型: 新生代, surivor, old humonous,

新生代 依然采用復制算法, 會STW, 多線程收集垃圾, 將存活的對象移動到surivor區域或者 old
old 垃圾收集過程, 和CMS很相似
1: 初始標記: 標記 所有GC-Roots根對象, 會STW,
2: 根區間掃描, 掃描幸存者取到old區對象的引用-->到 RSet中
3: 並發標記: GC-Roots往下traching的過程,工作線程也在運行,采用 STAB+寫屏障來避免漏標
4: 重新標記: 會STW, 工作線程運行產生的對象進行標記,
5: 並發清除: 回收垃圾對象, 然后將空閑的region區域保存到Cset中


免責聲明!

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



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