如何理解JVMZGC垃圾收集器

這期內(nèi)容當(dāng)中小編將會(huì)給大家?guī)?lái)有關(guān)如何理解JVM  ZGC垃圾收集器,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

10年積累的成都網(wǎng)站制作、網(wǎng)站設(shè)計(jì)經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶對(duì)網(wǎng)站的新想法和需求。提供各種問題對(duì)應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站制作后付款的網(wǎng)站建設(shè)流程,更有萊西免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。

如果下面的一些概念有些不清楚的可以先看深入理解JVM - 垃圾收集器和深入理解JVM - Shenandoah垃圾收集器。

ZGC(Z Garbage Collector)是一款由Oracle公司研發(fā)的,以低延遲為首要目標(biāo)的一款垃圾收集器。它是基于動(dòng)態(tài)Region內(nèi)存布局,(暫時(shí))不設(shè)年齡分代,使用了讀屏障、染色指針和內(nèi)存多重映射等技術(shù)來(lái)實(shí)現(xiàn)可并發(fā)的標(biāo)記-整理算法的收集器。在JDK 11新加入,還在實(shí)驗(yàn)階段,主要特點(diǎn)是:回收TB級(jí)內(nèi)存(最大4T),停頓時(shí)間不超過(guò)10ms。

動(dòng)態(tài)Region

ZGC的Region可以具有如圖所示的大、中、小三類容量:

如何理解JVM  ZGC垃圾收集器

  • 小型Region(Small Region):容量固定為2MB,用于放置小于256KB的小對(duì)象。

  • 中型Region(Medium Region):容量固定為32MB,用于放置大于等于256KB但小于4MB的對(duì)象?!?/p>

  • 大型Region(Large Region):容量不固定,可以動(dòng)態(tài)變化,但必須為2MB的整數(shù)倍,用于放置4MB或以上的大對(duì)象。每個(gè)大型Region中只會(huì)存放一個(gè)大對(duì)象,最小容量可低至4MB,所有大型Region可能小于中型Region。大型Region在ZGC的實(shí)現(xiàn)中是不會(huì)被重分配的,因?yàn)閺?fù)制一個(gè)大對(duì)象的代價(jià)非常高昂。

染色指針技術(shù)

HotSpot虛擬機(jī)的標(biāo)記實(shí)現(xiàn)方案有如下幾種:

(1)把標(biāo)記直接記錄在對(duì)象頭上(如Serial收集器);

(2)把標(biāo)記記錄在與對(duì)象相互獨(dú)立的數(shù)據(jù)結(jié)構(gòu)上(如G1、Shenandoah使用了一種相當(dāng)于堆內(nèi)存的1/64大小的,稱為BitMap的結(jié)構(gòu)來(lái)記錄標(biāo)記信息);

(3)直接把標(biāo)記信息記在引用對(duì)象的指針上(如ZGC)

染色指針是一種直接將少量額外的信息存儲(chǔ)在指針上的技術(shù)。目前在Linux下64位的操作系統(tǒng)中高18位是不能用來(lái)尋址的,但是剩余的46為卻可以支持64T的空間,到目前為止我們幾乎還用不到這么多內(nèi)存。于是ZGC將46位中的高4位取出,用來(lái)存儲(chǔ)4個(gè)標(biāo)志位,剩余的42位可以支持4T的內(nèi)存,如圖所示:

如何理解JVM  ZGC垃圾收集器

  • Linux下64位指針的高18位不能用來(lái)尋址,所有不能使用;

  • Finalizable:表示是否只能通過(guò)finalize()方法才能被訪問到,其他途徑不行;

  • Remapped:表示是否進(jìn)入了重分配集(即被移動(dòng)過(guò));

  • Marked1、Marked0:表示對(duì)象的三色標(biāo)記狀態(tài);

  • 最后42用來(lái)存對(duì)象地址,最大支持4T;

三色標(biāo)記

在并發(fā)的可達(dá)性分析算法中我們使用三色標(biāo)記(Tri-color Marking)來(lái)標(biāo)記對(duì)象是否被收集器訪問過(guò):

  • 白色:表示對(duì)象尚未被垃圾收集器訪問過(guò)。顯然在可達(dá)性分析剛剛開始的階段,所有的對(duì)象都是白色的,若在分析結(jié)束的階段,仍然是白色的對(duì)象,即代表不可達(dá)。

  • 黑色:表示對(duì)象已經(jīng)被垃圾收集器訪問過(guò),且這個(gè)對(duì)象的所有引用都已經(jīng)掃描過(guò)。黑色的對(duì)象代表已經(jīng)掃描過(guò),它是安全存活的,如果有其他對(duì)象引用指向了黑色對(duì)象,無(wú)須重新掃描一遍。黑色對(duì)象不可能直接(不經(jīng)過(guò)灰色對(duì)象)指向某個(gè)白色對(duì)象。

  • 灰色:表示對(duì)象已經(jīng)被垃圾收集器訪問過(guò),但這個(gè)對(duì)象上至少存在一個(gè)引用還沒有被掃描過(guò)。

可達(dá)性分析的掃描過(guò)程,其實(shí)就是一股以灰色為波峰的波紋從黑向白推進(jìn)的過(guò)程,但是在并發(fā)的推進(jìn)過(guò)程中會(huì)產(chǎn)生“對(duì)象消失”的問題,如圖:、

如何理解JVM  ZGC垃圾收集器

對(duì)象消失理論,只有同時(shí)滿足才會(huì)發(fā)生對(duì)象消失:

  • 賦值器插入了一條或多條從黑色對(duì)象到白色對(duì)象的新引用;

  • 賦值器刪除了全部從灰色對(duì)象到該白色對(duì)象的直接或間接引用;

要解決對(duì)象消失問題只需要破壞其中一條就行了,目前常用有兩種方案:

  • 增量更新(Incremental Update):增量更新要破壞的是第一個(gè)條件,當(dāng)黑色對(duì)象插入新的指向白色對(duì)象的引用關(guān)系時(shí),就將這個(gè)新插入的引用記錄下來(lái),等并發(fā)掃描結(jié)束之后,再將這些記錄過(guò)的引用關(guān)系中的黑色對(duì)象為根,重新掃描一次。這可以簡(jiǎn)化理解為,黑色對(duì)象一旦新插入了指向白色對(duì)象的引用之后,它就變回灰色對(duì)象了。

  • 原始快照(Snapshot At TheBeginning,SATB):原始快照要破壞的是第二個(gè)條件,當(dāng)灰色對(duì)象要?jiǎng)h除指向白色對(duì)象的引用關(guān)系時(shí),就將這個(gè)要?jiǎng)h除的引用記錄下來(lái),在并發(fā)掃描結(jié)束之后,再將這些記錄過(guò)的引用關(guān)系中的灰色對(duì)象為根,重新掃描一次。這也可以簡(jiǎn)化理解為,無(wú)論引用關(guān)系刪除與否,都會(huì)按照剛剛開始掃描那一刻的對(duì)象圖快照來(lái)進(jìn)行搜索。

以上無(wú)論是對(duì)引用關(guān)系記錄的插入還是刪除,虛擬機(jī)的記錄操作都是通過(guò)寫屏障實(shí)現(xiàn)的。CMS是基于增量更新來(lái)做并發(fā)標(biāo)記的,G1、Shenandoah則是用原始快照來(lái)實(shí)現(xiàn)。

染色指針的三大優(yōu)勢(shì)

(1)一旦某個(gè)Region的存活對(duì)象被移走之后,這個(gè)Region立即就能夠被釋放和重用掉,而不必等待整個(gè)堆中所有指向該Region的引用都被修正后才能清理,這使得理論上只要還有一個(gè)空閑Region,ZGC就能完成收集。而Shenandoah需要等到更新階段結(jié)束才能釋放回收集中的Region,如果Region里面對(duì)象都存活的時(shí)候,需要1:1的空間才能完成收集。

(2)染色指針可以大幅減少在垃圾收集過(guò)程中內(nèi)存屏障的使用數(shù)量,ZGC只使用了讀屏障。

(3)染色指針具備強(qiáng)大的擴(kuò)展性,它可以作為一種可擴(kuò)展的存儲(chǔ)結(jié)構(gòu)用來(lái)記錄更多與對(duì)象標(biāo)記、重定位過(guò)程相關(guān)的數(shù)據(jù),以便日后進(jìn)一步提高性能。

內(nèi)存多重映射

ZGC使用了內(nèi)存多重映射(Multi-Mapping)將多個(gè)不同的虛擬內(nèi)存地址映射到同一個(gè)物理內(nèi)存地址上,這是一種多對(duì)一映射,意味著ZGC在虛擬內(nèi)存中看到的地址空間要比實(shí)際的堆內(nèi)存容量來(lái)得更大。把染色指針中的標(biāo)志位看作是地址的分段符,那只要將這些不同的地址段都映射到同一個(gè)物理內(nèi)存空間,經(jīng)過(guò)多重映射轉(zhuǎn)換后,就可以使用染色指針正常進(jìn)行尋址了,效果如圖:

如何理解JVM  ZGC垃圾收集器

ZGC的多重映射只是它采用染色指針技術(shù)的伴生產(chǎn)物

讀屏障

當(dāng)對(duì)象從堆中加載的時(shí)候,就會(huì)使用到讀屏障(Load Barrier)。這里使用讀屏障的主要作用就是檢查指針上的三色標(biāo)記位,根據(jù)標(biāo)記位判斷出對(duì)象是否被移動(dòng)過(guò),如果沒有可以直接訪問,如果移動(dòng)過(guò)就需要進(jìn)行“自愈”(對(duì)象訪問會(huì)變慢,但也只會(huì)有一次變慢),當(dāng)“自愈”完成后,后續(xù)訪問就不會(huì)變慢了。

讀寫屏障可以理解成對(duì)象訪問的“AOP”操作

ZGC運(yùn)作過(guò)程

ZGC的運(yùn)作過(guò)程大致可劃分為以下四個(gè)大的階段:

如何理解JVM  ZGC垃圾收集器

  • 并發(fā)標(biāo)記(Concurrent Mark):與G1、Shenandoah一樣,并發(fā)標(biāo)記是遍歷對(duì)象圖做可達(dá)性分析的階段,它的初始標(biāo)記和最終標(biāo)記也會(huì)出現(xiàn)短暫的停頓,整個(gè)標(biāo)記階段只會(huì)更新染色指針中的Marked 0、Marked 1標(biāo)志位。

  • 并發(fā)預(yù)備重分配(Concurrent Prepare for Relocate):這個(gè)階段需要根據(jù)特定的查詢條件統(tǒng)計(jì)得出本次收集過(guò)程要清理哪些Region,將這些Region組成重分配集(Relocation Set)。ZGC每次回收都會(huì)掃描所有的Region,用范圍更大的掃描成本換取省去G1中記憶集的維護(hù)成本。

  • 并發(fā)重分配(Concurrent Relocate):重分配是ZGC執(zhí)行過(guò)程中的核心階段,這個(gè)過(guò)程要把重分配集中的存活對(duì)象復(fù)制到新的Region上,并為重分配集中的每個(gè)Region維護(hù)一個(gè)轉(zhuǎn)發(fā)表(Forward Table),記錄從舊對(duì)象到新對(duì)象的轉(zhuǎn)向關(guān)系。ZGC收集器能僅從引用上就明確得知一個(gè)對(duì)象是否處于重分配集之中,如果用戶線程此時(shí)并發(fā)訪問了位于重分配集中的對(duì)象,這次訪問將會(huì)被預(yù)置的內(nèi)存屏障所截獲,然后立即根據(jù)Region上的轉(zhuǎn)發(fā)表記錄將訪問轉(zhuǎn)發(fā)到新復(fù)制的對(duì)象上,并同時(shí)修正更新該引用的值,使其直接指向新對(duì)象,ZGC將這種行為稱為指針的“自愈”(Self-Healing)能力。

ZGC的染色指針因?yàn)椤白杂保⊿elf-Healing)能力,所以只有第一次訪問舊對(duì)象會(huì)變慢,而Shenandoah的Brooks轉(zhuǎn)發(fā)指針是每次都會(huì)變慢。

一旦重分配集中某個(gè)Region的存活對(duì)象都復(fù)制完畢后,這個(gè)Region就可以立即釋放用于新對(duì)象的分配,但是轉(zhuǎn)發(fā)表還得留著不能釋放掉,因?yàn)榭赡苓€有訪問在使用這個(gè)轉(zhuǎn)發(fā)表。

  • 并發(fā)重映射(Concurrent Remap):重映射所做的就是修正整個(gè)堆中指向重分配集中舊對(duì)象的所有引用,但是ZGC中對(duì)象引用存在“自愈”功能,所以這個(gè)重映射操作并不是很迫切。ZGC很巧妙地把并發(fā)重映射階段要做的工作,合并到了下一次垃圾收集循環(huán)中的并發(fā)標(biāo)記階段里去完成,反正它們都是要遍歷所有對(duì)象的,這樣合并就節(jié)省了一次遍歷對(duì)象圖的開銷。

ZGC存在的問題

ZGC最大的問題是浮動(dòng)垃圾。

浮動(dòng)垃圾

ZGC的停頓時(shí)間是在10ms以下,但是ZGC的執(zhí)行時(shí)間還是遠(yuǎn)遠(yuǎn)大于這個(gè)時(shí)間的。假如ZGC全過(guò)程需要執(zhí)行10分鐘,在這個(gè)期間由于對(duì)象分配速率很高,將創(chuàng)建大量的新對(duì)象,這些對(duì)象很難進(jìn)入當(dāng)次GC,所以只能在下次GC的時(shí)候進(jìn)行回收,這些只能等到下次GC才能回收的對(duì)象就是浮動(dòng)垃圾。

ZGC沒有分代概念,每次都需要進(jìn)行全堆掃描,導(dǎo)致一些“朝生夕死”的對(duì)象沒能及時(shí)的被回收。

解決方案

目前唯一的辦法是增大堆的容量,使得程序得到更多的喘息時(shí)間,但是這個(gè)也是一個(gè)治標(biāo)不治本的方案。如果需要從根本上解決這個(gè)問題,還是需要引入分代收集,讓新生對(duì)象都在一個(gè)專門的區(qū)域中創(chuàng)建,然后專門針對(duì)這個(gè)區(qū)域進(jìn)行更頻繁、更快的收集。

官方測(cè)試數(shù)據(jù)

停頓時(shí)間

在ZGC的停頓時(shí)間測(cè)試上,和其他收集器相比完全不在一個(gè)數(shù)量級(jí),如圖:

如何理解JVM  ZGC垃圾收集器

吞吐量

ZGC的“弱項(xiàng)”吞吐量方面,以低延遲為首要目標(biāo)的ZGC已經(jīng)達(dá)到了以高吞吐量為目標(biāo)Parallel Scavenge的99%,直接超越了G1,如圖:

如何理解JVM  ZGC垃圾收集器

優(yōu)缺點(diǎn)

優(yōu)點(diǎn):低停頓,高吞吐量,ZGC收集過(guò)程中額外耗費(fèi)的內(nèi)存小

缺點(diǎn):浮動(dòng)垃圾

上述就是小編為大家分享的如何理解JVM  ZGC垃圾收集器了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

網(wǎng)站題目:如何理解JVMZGC垃圾收集器
標(biāo)題路徑:http://muchs.cn/article0/ppjeio.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站收錄品牌網(wǎng)站建設(shè)、全網(wǎng)營(yíng)銷推廣App開發(fā)、電子商務(wù)營(yíng)銷型網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都seo排名網(wǎng)站優(yōu)化