1殴蓬、JVM垃圾收集器發(fā)展過程
1立润、第一階段:Serial(串行)收集器
特點(diǎn):單線程收集器狂窑,垃圾回收時(shí),必須暫停其他所有工作線程桑腮。
2泉哈、第二階段:Parallel(并行)收集器
特點(diǎn):充分利用多核特性,使用多線程完成清理工作。
3丛晦、第三階段:CMS(并發(fā))收集器
特點(diǎn):垃圾收集線程和用戶線程奕纫,可以同時(shí)執(zhí)行。
缺點(diǎn):CPU資源敏感采呐;無法處理浮動(dòng)垃圾若锁;大量?jī)?nèi)存碎片
初始標(biāo)記:【需要停頓】。只標(biāo)記GC ROOTS能直接關(guān)聯(lián)到的對(duì)象斧吐,速度很快
并發(fā)標(biāo)記:與用戶線程同時(shí)執(zhí)行又固。標(biāo)記GC ROOTS所有能關(guān)聯(lián)到的對(duì)象。
重新標(biāo)記:【需要停頓】煤率。修正并發(fā)標(biāo)記期間仰冠,因用戶程序執(zhí)行導(dǎo)致標(biāo)記變動(dòng)的記錄。
并發(fā)清除:與用戶線程同時(shí)執(zhí)行蝶糯,清理標(biāo)記的垃圾對(duì)象洋只。會(huì)產(chǎn)生浮動(dòng)垃圾
4、第四階段:G1(Garbage-First)(并發(fā))收集器
特點(diǎn):引入分區(qū)(分治昼捍、部分收集)识虚,弱化分代。關(guān)注最小時(shí)延妒茬,適合大尺寸堆內(nèi)存担锤。應(yīng)用在多處理器和大容量?jī)?nèi)存環(huán)境中,盡量縮短處理超大堆(大于4GB)時(shí)乍钻,產(chǎn)生的停頓肛循。帶有整理功能,相對(duì)CMS內(nèi)存碎片的產(chǎn)生率大大降低银择;STW可控多糠,停頓時(shí)間上加了預(yù)測(cè)機(jī)制
2、G1收集器對(duì)比CMS
1浩考、算法:
基于標(biāo)記-整理算法夹孔,碎片產(chǎn)生率降低。CMS有可能出現(xiàn)分配大對(duì)象時(shí)怀挠,無法得到連續(xù)空間而導(dǎo)致提前觸發(fā)一次full gc析蝴。
2、停頓時(shí)間可控:通過設(shè)置預(yù)期停頓時(shí)間绿淋,控制gc時(shí)間,避免應(yīng)用雪崩尝盼。
3吞滞、收集區(qū)域:G1雖然保留了新老代的概念,但是收集器是以整個(gè)區(qū)域?yàn)閱挝皇占摹1可以在Young GC中使用裁赠,CMS只能在Old區(qū)(常搭配ParNew收集年輕代)殿漠。
4、Remark階段高效:RSet解決跨代引用(如Old區(qū)域引用Young區(qū)域?qū)ο?佩捞、SATB算法記錄漏標(biāo)對(duì)象绞幌。
1.G1之前JVM內(nèi)存模型
image.png
2.G1收集器的內(nèi)存模型
Humongous:存放大對(duì)象(超過Region容量的一半)。
image.png
4一忱、G1重點(diǎn)參數(shù)
-XX:+UseG1GC:啟用G1收集器
-XX: G1HeapRegionSize:設(shè)置Region分區(qū)大小莲蜘。1M~32M,size越大垃圾存活時(shí)間長(zhǎng)帘营,gc間隔長(zhǎng)票渠,但gc的持續(xù)時(shí)間邊長(zhǎng)
-XX: MaxGCPauseMillis:最大GC停頓時(shí)間,軟目標(biāo)芬迄。
3问顷、G1收集器底層原理
1)G1運(yùn)作過程
1.初始標(biāo)記:標(biāo)記GC Roots能直接關(guān)聯(lián)到的對(duì)象。修改TAMS指針(Top at Mark Start)禀梳,【G1為每個(gè)Region分配了兩個(gè)指針杜窄,用于記錄回收過程中新對(duì)象的分配】,短暫停頓用戶線程算途,借用Minor GC時(shí)完成塞耕。
2.并發(fā)標(biāo)記:從GC Roots開始遞歸掃描整個(gè)堆,對(duì)堆中對(duì)象進(jìn)行可達(dá)性分析郊艘『煽疲【與用戶線程并發(fā)執(zhí)行洁段,并發(fā)過程漏標(biāo)對(duì)象使用SATB(snapshot-at-the-beginning)算法記錄】
3.最終標(biāo)記:短暫停頓用戶線程讶凉,處理并發(fā)階段遺留的漏標(biāo)對(duì)象。
4.篩選回收:對(duì)各個(gè)Region的回收價(jià)值和成本進(jìn)行排序烦秩,根據(jù)用戶期望的停頓時(shí)間狞贱,制定回收計(jì)劃刻获,回收一部分Region∠规遥【兩種回收模式蝎毡,Young GC、Mixed GC】
image.png
2)Young GC回收過程
分配一般對(duì)象(非巨型對(duì)象)時(shí)氧枣,所有E區(qū)使用達(dá)最大閾值且無法申請(qǐng)到足夠內(nèi)存時(shí)沐兵,進(jìn)行一次Young GC”慵啵回收所有S區(qū)和E區(qū)扎谎,將存活對(duì)象復(fù)制到O和另外S區(qū)碳想。
1.根掃描(初始標(biāo)記)。STW毁靶,掃描GC Roots對(duì)象
2.處理Dirty Card胧奔,更新Rset。
3.掃描Rset预吆。掃描Rset中所有Old區(qū)對(duì)Young區(qū)龙填、S區(qū)的引用。
4.對(duì)象拷貝拐叉。拷貝存活對(duì)象到S區(qū)和Old區(qū)岩遗。
3)Mixed GC回收過程
當(dāng)越來越多對(duì)象晉升到O區(qū)時(shí),為避免內(nèi)存耗盡巷嚣,虛擬機(jī)會(huì)觸發(fā)mixed gc喘先。回收整個(gè)E和S區(qū)廷粒,根據(jù)用戶期望停頓時(shí)間窘拯,回收一部分O區(qū)。
4坝茎、G1底層支持
1)三色標(biāo)記與漏標(biāo)問題
三色標(biāo)記
黑色:跟對(duì)象涤姊;或者該對(duì)象和他的子對(duì)象都被掃描過。
灰色:本身被掃描嗤放,但還未掃描該對(duì)象的子對(duì)象思喊。
白色:未被掃描的對(duì)象;掃描完所有對(duì)象后次酌,白色為不可達(dá)對(duì)象(垃圾對(duì)象)
漏標(biāo)問題
image.png
CMS中的解決方案:Incremental Update算法:當(dāng)一個(gè)白色的對(duì)象被一個(gè)黑色對(duì)象引用恨课,【將黑色對(duì)象重新標(biāo)記為灰色】,讓垃圾回收器重新掃描岳服。
G1中的解決方案:SATB(snapshot-at-the-beginning):當(dāng)B->C的引用鏈消失時(shí)剂公,將C推到GC的堆棧上,保證C還能被GC掃描到吊宋。
2)Rset解決跨代引用
現(xiàn)象:如果老年代引用了新生代的對(duì)象纲辽,那么回收新生代時(shí),要跟蹤老年代到新生代的所有引用璃搜。
image.png
Remembered Set:Hash表拖吼,Key是Region的地址,Value是對(duì)象的卡頁集合这吻〉醯担【其他Region中的對(duì)象引用本Region中對(duì)象的關(guān)系,表示誰引用了我的對(duì)象】
CardTable:如果一個(gè)O區(qū)CardTable中有對(duì)象指向Y區(qū)唾糯,就將它設(shè)置為Dirty籍铁,下次掃描時(shí)涡上,只需要掃描CardTable上是Dirty的內(nèi)存區(qū)域即可趾断。
3)TAMS(Top at Mark Start)指針
G1為每個(gè)Region區(qū)域設(shè)計(jì)了兩個(gè)TASM指針拒名。要達(dá)到與用戶線程并發(fā)運(yùn)行,必須要解決回收過程中新對(duì)象的分配芋酌。從Region區(qū)域劃分出一部分空間增显,用于記錄并發(fā)回收過程中的新對(duì)象產(chǎn)生,不納入垃圾回收范圍脐帝。
4)安全點(diǎn)與安全區(qū)域
安全點(diǎn):用戶線程暫停同云,GC線程開始工作,要確保用戶暫停的這行字節(jié)碼指令堵腹,【不會(huì)導(dǎo)致引用關(guān)系的變化】炸站,如【方法調(diào)用、循環(huán)跳轉(zhuǎn)疚顷、異常跳轉(zhuǎn)等】
主動(dòng)式中斷:設(shè)置一個(gè)標(biāo)志旱易,各用戶線程主動(dòng)輪訓(xùn)這個(gè)標(biāo)志,True則在最近的安全點(diǎn)上主動(dòng)中斷掛起腿堤。
安全區(qū)域:如果業(yè)務(wù)線程處于Sleep或者Blocked狀態(tài)阀坏,程序則沒辦法進(jìn)入安全點(diǎn)。作為安全點(diǎn)的擴(kuò)展【確保在某段代碼中笆檀,引用關(guān)系不會(huì)發(fā)生變化】