1黄锤、什么是跨代引用搪缨?
紅色的線表示由虛擬機(jī)棧中發(fā)出的引用。顯然B--->A鸵熟、E--->F都是跨代引用副编。
2、跨代引用對MonitorGC的影響
JVM GC 判斷對象是否可以回收使用可達(dá)性分析的方法流强,可達(dá)性分析首先需要找到 GC Roots 對象痹届。
常規(guī)GC-Root:
- 1)虛擬機(jī)棧(棧幀中的局部變量表)中引用的對象【Stack Local】呻待。
- 2)本地方法棧(native方法)引用的對象。
- 3)方法區(qū)中類靜態(tài)屬性队腐、靜態(tài)方法引用的對象蚕捉。
- 4)方法區(qū)中常量引用的對象。
MonitorGC個性GC-Root:
- 5) RememberSet數(shù)據(jù)結(jié)構(gòu)(CardTable是具體實(shí)現(xiàn)類似數(shù)組)
這里重點(diǎn)講一下CardTable:
??????? 作用:采用空間換時間香到,不需要掃描整個Heap空間鱼冀,降低MonitorGC耗時∮凭停跨代引用帶來的問題千绪,采用CardTable很好的規(guī)避了遍歷整個老年代的問題。
??????? HotSpot JVM的卡頁(Card Page)大小為512字節(jié)梗脾,卡表(Card Table)被實(shí)現(xiàn)為一個簡單的字節(jié)數(shù)組荸型,即卡表的每個標(biāo)記項(xiàng)為1個字節(jié)。
如上圖發(fā)現(xiàn):B炸茧、C所在的Card Page在CardTable中被標(biāo)記上了瑞妇。
【思考??】MonitorGC的GC-Root中包括CardTable,如何提高M(jìn)onitorGC效率梭冠?
就需要降低跨代引用的對象辕狰,盡量設(shè)置稍大些的From、To區(qū)域控漠,盡量將對象消滅在Young Gen區(qū)域蔓倍。同時也表示對象不是越早進(jìn)入老年代越好(老年代對象引用新生代對象就是一個很好的說明)!Q谓荨偶翅!。
3碉渡、跨代引用對CMS中 OldGC的影響
CMS-OldGC回收??分為7個步驟:
重點(diǎn)步驟解讀:
-
1聚谁、初始標(biāo)記(Initial Mark)
- 目標(biāo):進(jìn)行可達(dá)性分析,標(biāo)記GC ROOT能直接關(guān)聯(lián)到的對象滞诺。
- 標(biāo)記范圍:Young Gen + Old Gen形导。
- 線程:JDK1.7是單線程,JDK1.8是多線程(-XX:+CMSParallelInitialMarkEnabled調(diào)整)
- STW:
觸發(fā)Stop-The-World
- 特點(diǎn):速度極快
-
2习霹、并發(fā)標(biāo)記(Concurrent Mark)
- 目標(biāo):遍歷階段1初始標(biāo)記出來的存活對象骤宣,然后繼續(xù)遞歸標(biāo)記這些對象可達(dá)的對象。(黑白灰三色標(biāo)記法)序愚。
- 標(biāo)記范圍:Young Gen + Old Gen憔披。
- STW:不觸發(fā)
- 特點(diǎn):
慢,很耗時。
特殊操作:通過Old區(qū)卡片標(biāo)記(Card Marking)芬膝,提前把老年代空間邏輯劃分為相等大小的區(qū)域(Card Page)望门,如果引用關(guān)系發(fā)生改變,JVM會將發(fā)生改變的區(qū)域標(biāo)記位“臟區(qū)”(Dirty Card)锰霜。JVM會對“并發(fā)標(biāo)記”階段應(yīng)用線程新產(chǎn)生的對象及對象涉及的引用修改做記錄(Mod-Union Table)
-
3筹误、預(yù)清理(Preclean)
- 目標(biāo):2階段中記錄在Mod-Union Table的這些臟區(qū)會被找出來,刷新引用關(guān)系癣缅,清除“臟區(qū)”標(biāo)記厨剪。
- 標(biāo)記范圍: Old Gen。
- 線程:GC線程和應(yīng)用線程也是并發(fā)執(zhí)行
- STW:不觸發(fā)
- 特點(diǎn):速度一般
-
4友存、可中斷的預(yù)清理(Concurrent Abortable Preclean)
- 目標(biāo):降低垃圾回收時對應(yīng)用的暫停時間祷膳,整個過程最耗時步驟在5(最終標(biāo)記),所以4步驟提前進(jìn)行屡立。
觸發(fā)條件:此階段在Eden區(qū)使用超過2M時啟動直晨,當(dāng)然2M是默認(rèn)的閾值,可以通過參數(shù)修改膨俐。
- 標(biāo)記范圍:Young Gen + Old Gen勇皇。
- 處理From、To區(qū)對象焚刺,標(biāo)記可達(dá)到老年代的對象敛摘。
- 和3階段一樣,掃描處理Dirty Card中的對象乳愉。
終止邏輯:CMS為了避免這個階段沒有等到Minor GC而陷入無限等待着撩,提供了參數(shù)CMSMaxAbortablePrecleanTime ,默認(rèn)為5s匾委,含義是如果可中斷的預(yù)清理執(zhí)行超過5s,不管發(fā)沒發(fā)生Minor GC氓润,都會中止此階段赂乐,進(jìn)入Remark。
- 線程:GC線程和應(yīng)用線程也是并發(fā)執(zhí)行咖气。
- STW:不觸發(fā)
- 特點(diǎn):速度一般
- 特殊:下一個階段要執(zhí)行最耗時且STW的Remark階段挨措,Remark階段會將整個YoungGen作為GC-Root進(jìn)行操作,如果4階段能觸發(fā)一次MonitorGC就再好不過了崩溪。
-
5浅役、重新標(biāo)記(Final ReMark)
- 目標(biāo):GC事件中第二次(也是最后一次)STW階段,目的是完成老年代中
所有存活對象
的標(biāo)記伶唯。 - 標(biāo)記范圍:Young Gen + Old Gen觉既。
- 線程:GC線程獨(dú)占執(zhí)行
- STW:
觸發(fā)Stop-The-World
- 特點(diǎn):
速度較慢,可以說是整個CMS-Old GC的瓶頸點(diǎn)
。 - 特殊:
- 1瞪讼、遍歷新生代對象钧椰,重新標(biāo)記
- 2、根據(jù)GC Roots符欠,重新標(biāo)記
- 3嫡霞、遍歷老年代的Dirty Card,重新標(biāo)記
- 目標(biāo):GC事件中第二次(也是最后一次)STW階段,目的是完成老年代中
-
6希柿、并發(fā)清除(Concurrent Sweep)
- 目標(biāo):根據(jù)標(biāo)記結(jié)果清除垃圾對象诊沪。
- 標(biāo)記范圍:Old Gen。
- 線程:GC線程和應(yīng)用線程也是并發(fā)執(zhí)行
- STW:不觸發(fā)
- 特點(diǎn):速度一般曾撤。
-
7端姚、并發(fā)重置(Concurrent Reset)
- 目標(biāo):重置CMS算法相關(guān)的內(nèi)部數(shù)據(jù), 為下一次GC循環(huán)做準(zhǔn)備。
- 線程:GC線程和應(yīng)用線程也是并發(fā)執(zhí)行
- STW:不觸發(fā)
- 特點(diǎn):速度一般盾戴。
7步圖解:
4寄锐、問題思考??:
【思考??】CMS oldgc中remark耗時問題,跨代引用是圖一中的B--->A 還是 E--->F尖啡?
答案:E--->F橄仆。
通過:-XX:+CMSScavengeBeforeRemark
,觸發(fā)MonitorGC降低的就是YoungGen區(qū)的對象,從而達(dá)到標(biāo)記源頭減少衅斩,降低remark時間盆顾。
【思考??】CMS 跨代引用是圖一中的B--->A 有何危害,虛擬機(jī)是如何避開的畏梆?
答案:CardTable您宪。
邏輯:采用創(chuàng)建CardTable空間區(qū)域,來避免掃整個老年代奠涌。當(dāng)B無引用的時候宪巨,cardTable會被標(biāo)記,一次MonitorGC就會回收??掉溜畅。B是如何做到?jīng)]引用的捏卓,同E--->F是一樣的邏輯。
【思考??】CMS里有兩個需要STW的階段:initial mark慈格,remark怠晴、這兩個標(biāo)記有什么不一樣么?使用的GC-Root一樣么浴捆?
答案:不一樣蒜田。
初始標(biāo)記:使用的是常規(guī)的GC-Root(虛擬機(jī)棧棧幀中的局部變量表、本地方法棧native方法选泻、方法區(qū)中類的靜態(tài)屬性和方法冲粤、方法區(qū)中常量等引用的對象)
重新標(biāo)記:
- 常規(guī)的GC-Root美莫。(只有MonitorGC才會使用跟可達(dá)分析)
- 新生代所有對象。
- 遍歷老年代的DirtyCard(ModUnionTable)色解。
【思考??】同時帶來了另外一個問題茂嗓,MonitorGC可沒有遍歷整個老年代,而是采用CardTable通過時間換空間的做法科阎,CMS-OldGC為什么采用遍歷新生代所有的對象呢述吸?
??????? 這就是YoungGen 與 OldGen存在明顯的差異:
- 老年代對象都是經(jīng)歷過多次GC回收??存活下來了,對象存在的變數(shù)極低锣笨。所以采用空間換時間效果較好蝌矛。
- 新生代對象屬于變化特別快的區(qū)域,如果采用空間換時間错英,既浪費(fèi)了空間入撒,也沒有提升性能。
【思考??】既然initial mark階段+concurrent mark階段已經(jīng)掃果了young gen 為何還要再次Remark椭岩?
【思考??】CardTable與mod-union table有什么關(guān)系茅逮,都是干什么的?