CMS收集器
全稱:Concurrent Mark Sweep
特點
- 「采用標記-清除算法實現」 2.和Parallel 系列的收集器注重點不同:
Parallel 注重吞吐量CMS注重STW的停頓時間
工作流程
1.初始標記
「CMS inital mark」
?
標記GC Roots直接關聯的對象**「需要STW」**
?
2.并發標記
CMS concurrent mark
?
根據上一步和GC Roots直接關聯的對象進行遍歷整個堆里面的對象圖并進行標記,由于是并發的所以并 「不需要停頓用戶線程」 ,但是比較耗時因為遍歷整個對象圖。
?
3.重新標記
CMS remark
?
在并發標記期間由于和用戶線程是并發的,所以這段期間用戶線程可能更新了引用,所以需要進行一次修正(詳見上一篇文章中講到的 「增量更新」 ) 需要 「STW」 ,STW停頓時間比初始標記時間長,但是并沒有并發標記運行時間長
?
4.并發清除
?
清除刪掉被標記為垃圾的對象,由于采用的是標記-清除算法,所以并不需要移動存活對象因此是可以并發的。(當內存碎片嚴重到不足以分配對象時其實還是需要進行標記-整理算法的,這個時候就會提前觸發FullGC。)
?
「注意」 :在并發階段產生的**“浮動垃圾”**(并發時用戶線程產生的垃圾),需要等到下一次垃圾回收才能進行清理;而且并發的時候需要預留一部分內存空間供用戶線程使用,所以不能等到老年代完全用完在進行清理。JDK5的默認設置是當老年代使用了65%的空間就會觸發GC。
G1 收集器
特點
思維方式的重大轉變:
?
G1之前的收集器都是分代收集的思想,根據不同的代采用不同的GC:新生代(Minor GC),老年代(Major GC),整個JAVA堆(Full GC)。
?
但是GC是根據哪塊內存中垃圾數量多回收效益最大來區分的,面向的是堆內存中的任意一塊內存來組成回收集(Collection Set)進行回收。
實現
?
基于Region的堆內存布局來實現該回收過程。不再以固定大小及固定數量來劃分分代區域,而是把連續的堆內存區域進行劃分為各自獨立大小相等的區域(Region),每一個Region都可以根據需要扮演新生代中的Enen空間,Survivor空間,或者老年代。收集器根據扮演不同角色的Region采用不同策略去處理。
?
Region中有一類特殊的Humongous區域,專門用來存儲大對象。
G1認為一個對象的大小超過了一個Region空間的一半就認為該對象是大對象,如果超過了整個Region空間的超大對象將會被存放在連續的Humongous Region中,因此該區域一般會被作為老年代看待。
優點
「1.建立可預測的停頓時間模型」 :由于采用的是Region,因此回收單元作為Region即每次回收都是Region大小的整數倍。
G1會跟蹤Region區域里面垃圾堆,計算出價值(回收所獲得的空間大小以及回收所需時間的經驗值),接著在后臺維護一個優先級列表,根據用戶設置的允許停頓時間來進行回收價值最大的Region區域。也就是“Garbage First” 的由來。
「2.內存碎片」 整體上采用的是標記-整理,但是在兩個Region中實際上還是采用的復制算法,所以不會出現內存碎片問題。
缺點
「1.浪費額外內存來維護收集器工作」
跨代引用避免全堆掃描之前說過是采用 「記憶集」 的方式來解決,在G1中也一樣。每個Region中都有自己的記憶集 「但是」 在G1中每個Region除了需要記錄別的Region指向自己的指針,還需要標記這些指針分別在哪些卡頁范圍內。其實本質上說是哈希表,Key是別的Region的起始地址,Value是一個集合存儲的元素是卡表的索引號。因此實現起來比原有的記憶集要復雜,而且Region的數量比之前的分代數量要多得多,所以記憶集的維護占用了更高的內存
?
G1至少要耗費大約相當于JAVA堆容量的10%到20%來存儲維持收集器正常工作
?
「2.不僅用到寫后屏障還用到了寫前屏障」
上一小點中已經講到維護卡表是需要進行添加寫后屏障來完成更新卡表的操作的,但是G1還用到了寫前屏障:由于使用的是原始快照來保證可以進行并發標記的基礎,對比與增量更新來說雖然能夠減少最終標記的停頓時間,但是相比于收集器,這款收集器不僅采用了寫前屏障也采用了寫后屏障導致最終的效率降低
工作流程
與之前不同的是 「最后一處」 ,這個步驟需要進行 「更新Region的統計數據,對所有的Region的回收價值和成本進行排序,然后根據用戶設定的期望停頓時間進行決定選擇哪幾個Region構成回收集,然后將一部分的Region中存活對象復制到另外一個空的Region空間中,隨后進行清理掉整個舊的Region空間」 。是不是復制算法(針對與Region來說),因為涉及對象移動,所以需要 「暫停用戶線程」 。
總結
到此,如果讀者之前閱讀過筆者之前的關于垃圾回收器講解的文章,其實已經對現在大多數垃圾回收器機制和實現原理了解的差不多了,讀者有興趣可以自行去看Shenandoah收集器和ZGC收集器,本文不在敘述,主要確實文章內容有點太長了哈哈。后面的文章將不在分析垃圾回收器的知識,但是還是會更新關于JVM的文章。
-
GC
+關注
關注
0文章
9瀏覽量
17077 -
cms
+關注
關注
0文章
59瀏覽量
10956 -
JVM
+關注
關注
0文章
157瀏覽量
12210 -
收集器
+關注
關注
0文章
30瀏覽量
3126
發布評論請先 登錄
相關推薦
評論