java CMS,G1垃圾收集器工作流程原理淺析
JVM內(nèi)存空間基礎(chǔ)知識點(基于JDk1.8)
1.方法區(qū):邏輯概念,元空間,方法區(qū)主要用于存儲類的信息、常量池、方法數(shù)據(jù)、方法代碼等。方法區(qū)邏輯上屬于堆的一部分,但是為了與堆進(jìn)行區(qū)分,通常又叫“非堆”。
2.程序計數(shù)器:程序計數(shù)器可以看作當(dāng)前線程所執(zhí)行的字節(jié)碼的行號指示器。如果線程執(zhí)行的是Java方法那么這個計數(shù)器記錄的是正在執(zhí)行的虛擬機(jī)字節(jié)碼指令地址。如果執(zhí)行的是Native方法,這個計數(shù)器為空。
2.Java虛擬機(jī)棧:Java虛擬機(jī)棧跟程序計數(shù)器一樣是線程私有的,它的生命周期和線程相同。虛擬機(jī)棧描述的是Java方法執(zhí)行的內(nèi)存模型:每個方法在執(zhí)行時都會創(chuàng)建一個棧幀用于存儲局部變量表、操作數(shù)棧、動態(tài)鏈接、方法出口等信息。每一個方法從調(diào)用到執(zhí)行完成的過程,就對應(yīng)一個棧幀在虛擬機(jī)棧中入棧到出棧的過程。
3.本地方法棧:本地方法棧與虛擬機(jī)棧作用相似,它們之間的區(qū)別是虛擬機(jī)棧為虛擬機(jī)執(zhí)行Java方法服務(wù),而本地方法棧則為虛擬機(jī)使用到的Native方法服務(wù)。
4.Java堆: Java堆通常是Java虛擬機(jī)所管理的內(nèi)存中最大的一塊。Java堆是被鎖有線程共享的一塊內(nèi)存區(qū)域,在虛擬機(jī)啟動時創(chuàng)建。這塊區(qū)域唯一的目的就是存放對象實例,幾乎所有對象實例都在該區(qū)域分配內(nèi)存。
Java堆時垃圾收集器管理的主要區(qū)域(GC堆),從內(nèi)存回收的角度(收集器一般采用分代收集算法),Java堆還可以細(xì)分為:新生代和老年代。新生代再細(xì)分有:Eden空間、From Survivor空間、To Survivor空間。
1)簡述垃圾收集算法
1.標(biāo)記-清除算法:
兩遍掃描,第一遍掃描枚舉GCRoots根節(jié)點對象標(biāo)記出不可回收對象,第二遍掃描找到可回收對象進(jìn)行清理。算法簡單,存活對象較多的情況下效率比較高,但是容易產(chǎn)生一個內(nèi)存碎片化的問題。
2.復(fù)制算法:
一次掃描找到存活對象進(jìn)行復(fù)制,效率較高。適用于存活對象較少的情況,新生代垃圾收集(新生代對象存活率百分之二)。但是對內(nèi)存要求較高,一半的內(nèi)存空間預(yù)留。
3.標(biāo)記-整理算法:
兩遍掃描找到存活對象并進(jìn)行移動整理。內(nèi)存不會造成浪費,但是回收效率較低。
4.分代收集算法:前幾種算法的組合
2)垃圾收集器介紹
1.serial系列(標(biāo)記整理算法)
serial-serialold組合,單線程垃圾收集器,GC線程工作的時候會暫停所有用戶線程,產(chǎn)生stop the world。適用于內(nèi)存較小的內(nèi)存垃圾回收,簡單而高效,不存在多線程交互開銷,效率高。一般是硬件能力不足的情況下推動產(chǎn)生的。
2.Parallel系列(標(biāo)記整理算法)
Parallel 并行線程垃圾收集器,GC線程工作的時候暫停用戶線程,產(chǎn)生stop the world。內(nèi)存較大時,單線程GC工作時造成的stop the world時間過長,影響用戶體驗。Parallel系列垃圾收集器GC線程并行清理,減少gc工作線程時間。
3.CMS垃圾收集器。重點(垃圾清除算法)
CMS垃圾收集器工作流程
1.初始標(biāo)記:枚舉GCRoots對象,暫停用戶線程,掃描對象較少,Stop the world時間短。
2.并發(fā)標(biāo)記:GC線程,用戶線程并發(fā)工作,耗時時間最久的一部分內(nèi)容(80%GC時間),GC線程搶占CPU,對用戶線程有影響。由于用戶線程是并發(fā)執(zhí)行的,用戶線程會造成一些對象的引用改變,產(chǎn)生新的垃圾對象。
3.重新標(biāo)記:短暫的stop the world,不會有對象的狀態(tài)改變。并發(fā)標(biāo)記產(chǎn)生的新的垃圾會在這階段被標(biāo)記出來。
4.并發(fā)清理: GC線程和用戶線程并發(fā)執(zhí)行,產(chǎn)生的浮動垃圾由下一次垃圾回收清理。
缺點:CMS進(jìn)行垃圾收集的時候需要預(yù)留一定的內(nèi)存空間給用戶線程工作(默認(rèn)68%,可設(shè)置),在內(nèi)容空間不足時,會導(dǎo)致回收失敗,此時會通過serialold進(jìn)行垃圾回收,速度特別慢。
CMS垃圾收集器采用的是三色標(biāo)記算法。
由于CMS采用的是并發(fā)標(biāo)記,在GC線程工作時,此時有一個黑色的對象的引用對象被置為null,由于黑色對象不需要再被重新掃描,此時又沒有其他引用跟置為null的引用對象產(chǎn)生關(guān)聯(lián)時。就會產(chǎn)生一個浮動垃圾的情況。
在一個灰色對象的引用白色對象引用被置為null,并將黑色對象的屬性引用指向該白色對象時,會產(chǎn)生一個漏標(biāo)現(xiàn)象。CMS采用三色標(biāo)記法+incremental update算法,在黑色對象引用增加時,將黑色引用對象置為灰色,下次重新掃描。
4.G1垃圾收集器。重點,(region內(nèi)標(biāo)記清楚算法,region之間復(fù)制算法)
G1邏輯分代概念。基于整個內(nèi)存劃分為四個不同類型的內(nèi)存區(qū)域。
H:存放大對象
每個region都有一個RememberrdSet內(nèi)存區(qū)域 記錄了其他region到benregion的引用,垃圾收集器只需掃描該區(qū)域即可。
G1分為YGC(新生代回收),F(xiàn)GC(整個堆內(nèi)存回收),MixedGC(可設(shè)置MixedGC啟動的內(nèi)存大?。?br> MixedGC類似于CMS,在堆內(nèi)存空間使用超過45%時,產(chǎn)生MixedGC。G1采用三色標(biāo)記法+SATB算法,在灰色對象的白色引用對象引用清楚時,置入堆棧對象引用,后續(xù)掃描RSet枚舉根對象判斷是有有新的引用指向該白色對象。沒有則進(jìn)行清楚。
CMS垃圾清理流程圖 及 具體邏輯
1、新創(chuàng)建的對象一般會被分配在新生代中。常用的新生代的垃圾回收器是 ParNew 垃圾回收器,它按照 8:1:1 將新生代分成 Eden 區(qū),以及兩個 survivor 區(qū)。創(chuàng)建的對象將 Eden 區(qū)全部擠滿,這個對象就是「擠滿新生代的最后一個對象」。此時,Minor Gc 就觸發(fā)了。
2、在正式 Minor Gc 前,JVM 會先檢查新生代中對象,是比老年代中剩余空間大還是小。Minor Gc 之后 survivor 區(qū)不放剩余對象,這些對象就要進(jìn)入到老年代,所以要提前檢查老年代是不是夠用。
3、老年代剩余空間如果大于新生代中的對象大小,那就直接 Minor Gc,Gc 完survivor 不夠放,老年代夠放。
老年代剩余空間如果小于新生代中的對象大小,這時候就要進(jìn)入老年代空間分配擔(dān)保規(guī)則。
4、老年代空間分配擔(dān)保規(guī)則:如果老年代中剩余空間大小,大于歷次 Minor Gc 之后剩余對象的大小,那就允許進(jìn)行 Minor Gc。因為從概率上來說,以前的放的下,這次的也應(yīng)該放的下。那就有兩種情況:
一:老年代中剩余空間大小,大于歷次 Minor Gc 之后剩余對象的大小,進(jìn)行 Minor Gc
二:老年代中剩余空間大小,小于歷次 Minor Gc 之后剩余對象的大小,進(jìn)行 Ful GC,把老年代空出來再檢查。
結(jié)合第四步,開啟老年代空間分配擔(dān)保規(guī)則只能說是大概率上來說,Minor Gc 剩余后的對象夠放到老年代,如果放不下:Minor Gc 后會有這樣三種情況:
Minor Gc 之后的對象足夠放到 survivor 區(qū),Gc 結(jié)束。
Minor Gc 之后的對象不夠放到 survivor 區(qū),接著進(jìn)入到老年代,老年代能放下,那也可以,GC 結(jié)束
Minor Gc 之后的對象不夠放到 survivor 區(qū),老年代也放不下,那就只能 Full GC。
以上是成功 GC 的例子,以下3 中情況,會導(dǎo)致 GC 失敗,報 OOM:
緊接上一節(jié) Ful GC 之后,老年代任然放不下剩余對象,就只能 00M.
未開啟老年代分配擔(dān)保機(jī)制,且一次FuI GC 后,老年代任然放不下剩余對象,也只能 OOM。
開啟老年代分配擔(dān)保機(jī)制,但是擔(dān)保不通過,一次Ful GC 后,老年代任然放不下剩余對象,也是能 OOM。
注:
老年代分配擔(dān)保機(jī)制在JDK1.5以及之前版本中默認(rèn)是關(guān)閉的,需要通過HandlePromotionFailure手動指定,JDK1.6之后就默認(rèn)開啟。如果我們生產(chǎn)環(huán)境服務(wù)使用的是JDK/1.7JDK1.8,所以不用再手動去開啟擔(dān)保機(jī)制。
Full GC主要指新生代、老年代、metaspace上的全部GC文章來源:http://www.zghlxwxcb.cn/news/detail-857123.html
使用G1垃圾回收器的例子文章來源地址http://www.zghlxwxcb.cn/news/detail-857123.html
到了這里,關(guān)于深入理解JAVA垃圾收集器CMS,G1工作流程原理 GC流程圖 什么社會觸發(fā)Minor GC?觸發(fā)MinorGC過程。Full GC 過程。的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!