無(wú)語(yǔ)!4年工作經(jīng)驗(yàn)問(wèn)CMS垃圾收集器

面試官:今天還是來(lái)聊聊CMS垃圾收集器唄?
候選者:嗯啊…
候選者:如果用Seria和Parallel系列的垃圾收集器:在垃圾回收的時(shí),用戶線程都會(huì)完全停止,直至垃圾回收結(jié)束!

候選者:CMS的全稱:Concurrent Mark Sweep,翻譯過(guò)來(lái)是「并發(fā)標(biāo)記清除」
候選者:用CMS對(duì)比上面的垃圾收集器(Seria和Parallel和parNew):它最大的不同點(diǎn)就是「并發(fā)」:在GC線程工作的時(shí)候,用戶線程「不會(huì)完全停止」,用戶線程在「部分場(chǎng)景下」與GC線程一起并發(fā)執(zhí)行。
候選者:但是,要理解的是,無(wú)論是什么垃圾收集器,Stop The World是一定無(wú)法避免的!
候選者:CMS只是在「部分」的GC場(chǎng)景下可以讓GC線程與用戶線程并發(fā)執(zhí)行
候選者:CMS的設(shè)計(jì)目標(biāo)是為了避免「老年代 GC」出現(xiàn)「長(zhǎng)時(shí)間」的卡頓(Stop The World)

面試官:那你清楚CMS的工作流程嗎?
候選者:只了解一點(diǎn)點(diǎn),不能多了。
候選者:CMS可以簡(jiǎn)單分為5個(gè)步驟:初始標(biāo)記、并發(fā)標(biāo)記、并發(fā)預(yù)清理、重新標(biāo)記以及并發(fā)清除
候選者:從步驟就不難看出,CMS主要是實(shí)現(xiàn)了「標(biāo)記清除」垃圾回收算法
面試官:嗯…是的
候選者:我就從「初始標(biāo)記」來(lái)開始吧
候選者:「初始標(biāo)記」會(huì)標(biāo)記GCRoots「直接關(guān)聯(lián)」的對(duì)象以及「年輕代」指向「老年代」的對(duì)象
候選者:「初始標(biāo)記」這個(gè)過(guò)程是會(huì)發(fā)生Stop The World的。但這個(gè)階段的速度算是很快的,因?yàn)闆]有「向下追溯」(只標(biāo)記一層)

候選者:在「初始標(biāo)記」完了之后,就進(jìn)入了「并發(fā)標(biāo)記」階段啦
候選者:「并發(fā)標(biāo)記」這個(gè)過(guò)程是不會(huì)停止用戶線程的(不會(huì)發(fā)生 Stop The World)。這一階段主要是從GC Roots向下「追溯」,標(biāo)記所有可達(dá)的對(duì)象。
候選者:「并發(fā)標(biāo)記」在GC的角度而言,是比較耗費(fèi)時(shí)間的(需要追溯)

候選者:「并發(fā)標(biāo)記」這個(gè)階段完成之后,就到了「并發(fā)預(yù)處理」階段啦
候選者:「并發(fā)預(yù)處理」這個(gè)階段主要想干的事情:希望能減少下一個(gè)階段「重新標(biāo)記」所消耗的時(shí)間
候選者:因?yàn)橄乱粋€(gè)階段「重新標(biāo)記」是需要Stop The World的
面試官:嗯…
候選者:「并發(fā)標(biāo)記」這個(gè)階段由于用戶線程是沒有被掛起的,所以對(duì)象是有可能發(fā)生變化的
候選者: 可能有些對(duì)象,從新生代晉升到了老年代??赡苡行?duì)象,直接分配到了老年代(大對(duì)象)??赡芾夏甏蛘咝律膶?duì)象引用發(fā)生了變化…
面試官:那這個(gè)問(wèn)題,怎么解決呢?
候選者:針對(duì)老年代的對(duì)象,其實(shí)還是可以借助類card table的存儲(chǔ)(將老年代對(duì)象發(fā)生變化所對(duì)應(yīng)的卡頁(yè)標(biāo)記為dirty)
候選者:所以「并發(fā)預(yù)處理」這個(gè)階段會(huì)掃描可能由于「并發(fā)標(biāo)記」時(shí)導(dǎo)致老年代發(fā)生變化的對(duì)象,會(huì)再掃描一遍標(biāo)記為dirty的卡頁(yè)
面試官:嗯…
候選者:對(duì)于新生代的對(duì)象,我們還是得遍歷新生代來(lái)看看在「并發(fā)標(biāo)記」過(guò)程中有沒有對(duì)象引用了老年代..
候選者:不過(guò)JVM里給我們提供了很多「參數(shù)」,有可能在這個(gè)過(guò)程中會(huì)觸發(fā)一次 minor GC(觸發(fā)了minor GC 是意味著就可以更少地遍歷新生代的對(duì)象)

候選者:「并發(fā)預(yù)處理」這個(gè)階段階段結(jié)束后,就到了「重新標(biāo)記」階段
候選者:「重新標(biāo)記」階段會(huì)Stop The World,這個(gè)過(guò)程的停頓時(shí)間其實(shí)很大程度上取決于上面「并發(fā)預(yù)處理」階段(可以發(fā)現(xiàn),這是一個(gè)追趕的過(guò)程:一邊在標(biāo)記存活對(duì)象,一邊用戶線程在執(zhí)行產(chǎn)生垃圾)

候選者:最后就是「并發(fā)清除」階段,不會(huì)Stop The World
候選者:一邊用戶線程在執(zhí)行,一邊GC線程在回收不可達(dá)的對(duì)象
候選者:這個(gè)過(guò)程,還是有可能用戶線程在不斷產(chǎn)生垃圾,但只能留到下一次GC 進(jìn)行處理了,產(chǎn)生的這些垃圾被叫做“浮動(dòng)垃圾”
候選者:完了以后會(huì)重置 CMS 算法相關(guān)的內(nèi)部數(shù)據(jù),為下一次 GC 循環(huán)做準(zhǔn)備

面試官:嗯,CMS的回收過(guò)程,我了解了
面試官:聽下來(lái),其實(shí)就是把垃圾回收的過(guò)程給”細(xì)分”了,然后在某些階段可以不停止用戶線程,一邊回收垃圾,一邊處理請(qǐng)求,來(lái)減少每次垃圾回收時(shí) Stop The World的時(shí)間
面試官:當(dāng)然啦,中間也做了很多的優(yōu)化(dirty card標(biāo)記、可能中途觸發(fā)minor gc等等,在我理解下,這些應(yīng)該都提供了CMS的相關(guān)參數(shù)配置)
面試官:不過(guò),我看現(xiàn)在很多企業(yè)都在用G1了,那你覺得CMS有什么缺點(diǎn)呢?
候選者:1.空間需要預(yù)留:CMS垃圾收集器可以一邊回收垃圾,一邊處理用戶線程,那需要在這個(gè)過(guò)程中保證有充足的內(nèi)存空間供用戶使用。
候選者:如果CMS運(yùn)行過(guò)程中預(yù)留的空間不夠用了,會(huì)報(bào)錯(cuò)(Concurrent Mode Failure),這時(shí)會(huì)啟動(dòng) Serial Old垃圾收集器進(jìn)行老年代的垃圾回收,會(huì)導(dǎo)致停頓的時(shí)間很長(zhǎng)。
候選者:顯然啦,空間預(yù)留多少,肯定是有參數(shù)配置的
候選者:2. 內(nèi)存碎片問(wèn)題:CMS本質(zhì)上是實(shí)現(xiàn)了「標(biāo)記清除算法」的收集器(從過(guò)程就可以看得出),這會(huì)意味著會(huì)產(chǎn)生內(nèi)存碎片
候選者:由于碎片太多,又可能會(huì)導(dǎo)致內(nèi)存空間不足所觸發(fā)full GC,CMS一般會(huì)在觸發(fā)full GC這個(gè)過(guò)程對(duì)碎片進(jìn)行整理
候選者:整理涉及到「移動(dòng)」/「標(biāo)記」,那這個(gè)過(guò)程肯定會(huì)Stop The World的,如果內(nèi)存足夠大(意味著可能裝載的對(duì)象足夠多),那這個(gè)過(guò)程卡頓也是需要一定的時(shí)間的。
面試官:嗯…

候選者:使用CMS的弊端好像就是一個(gè)死循環(huán):
候選者:1. 內(nèi)存碎片過(guò)多,導(dǎo)致空間利用率減低。
候選者:2. 空間本身就需要預(yù)留給用戶線程使用,現(xiàn)在碎片內(nèi)存又加劇了空間的問(wèn)題,導(dǎo)致有可能垃圾收集器降級(jí)為Serial Old,卡頓時(shí)間更長(zhǎng)。
候選者:3. 要處理內(nèi)存碎片的問(wèn)題(整理),同樣會(huì)卡頓
候選者:不過(guò),技術(shù)實(shí)現(xiàn)就是一種trade-off(權(quán)衡),不可能你把所有的事情都做得很完美
候選者:了解這個(gè)過(guò)程,是非常有趣的
面試官:那G1垃圾收集器你了解嗎
候選者:只了解一點(diǎn)點(diǎn),不能多了
候選者:不過(guò),留到下次吧,先讓你消化下,不然怕你頂不住了。
本文總結(jié):
- CMS垃圾回收器設(shè)計(jì)目的:為了避免「老年代 GC」出現(xiàn)「長(zhǎng)時(shí)間」的卡頓(Stop The World)
- CMS垃圾回收器回收過(guò)程:初始標(biāo)記、并發(fā)標(biāo)記、并發(fā)預(yù)處理、重新標(biāo)記和并發(fā)清除。初始標(biāo)記以及重新標(biāo)記這兩個(gè)階段會(huì)Stop The World
- CMS垃圾回收器的弊端:會(huì)產(chǎn)生內(nèi)存碎片&&需要空間預(yù)留:停頓時(shí)間是不可預(yù)知的


對(duì)線面試官PDF版本,可+V: java3yyy 免費(fèi)領(lǐng)取