成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

一文了解JVM全部垃圾回收器,從Serial到ZGC

jasperyang / 1605人閱讀

摘要:是目前的實(shí)驗(yàn)收集器。也是需要暫停程序一切的工作,然后多線(xiàn)程執(zhí)行垃圾回收。與最大的不同,它關(guān)注的是垃圾回收的吞吐量。這里的吞吐量指的是總時(shí)間與垃圾回收時(shí)間的比例。篩選回收,評(píng)估標(biāo)記垃圾,根據(jù)模式回收垃圾。

《對(duì)象搜索算法與回收算法》介紹了垃圾回收的基礎(chǔ)算法,相當(dāng)于垃圾回收的方法論。接下來(lái)就詳細(xì)看看垃圾回收的具體實(shí)現(xiàn)。

上文提到過(guò)現(xiàn)代的商用虛擬機(jī)的都是采用分代收集的,不同的區(qū)域用不同的收集器。常用的7種收集器,其適用的范圍如圖所示


Serial、ParNew、Parallel Scavenge用于新生代;
CMS、Serial Old、Paralled Old用于老年代。
并且他們相互之間以相對(duì)固定的組合使用(具體組合關(guān)系如上圖)。G1是一個(gè)獨(dú)立的收集器不依賴(lài)其他6種收集器。ZGC是目前JDK 11的實(shí)驗(yàn)收集器。

下面來(lái)看看各個(gè)收集器的特性

Serial收集器

Serial,是單線(xiàn)程執(zhí)行垃圾回收的。當(dāng)需要執(zhí)行垃圾回收時(shí),程序會(huì)暫停一切手上的工作,然后單線(xiàn)程執(zhí)行垃圾回收。

因?yàn)樾律奶攸c(diǎn)是對(duì)象存活率低,所以收集算法用的是復(fù)制算法,把新生代存活對(duì)象復(fù)制到老年代,復(fù)制的內(nèi)容不多,性能較好。

單線(xiàn)程地好處就是減少上下文切換,減少系統(tǒng)資源的開(kāi)銷(xiāo)。但這種方式的缺點(diǎn)也很明顯,在GC的過(guò)程中,會(huì)暫停程序的執(zhí)行。若GC不是頻繁發(fā)生,這或許是一個(gè)不錯(cuò)的選擇,否則將會(huì)影響程序的執(zhí)行性能。
對(duì)于新生代來(lái)說(shuō),區(qū)域比較小,停頓時(shí)間短,所以比較使用。

ParNew收集器

ParNew同樣用于新生代,是Serial的多線(xiàn)程版本,并且在參數(shù)、算法(同樣是復(fù)制算法)上也完全和Serial相同。

Par是Parallel的縮寫(xiě),但它的并行僅僅指的是收集多線(xiàn)程并行,并不是收集和原程序可以并行進(jìn)行。ParNew也是需要暫停程序一切的工作,然后多線(xiàn)程執(zhí)行垃圾回收。

因?yàn)槭嵌嗑€(xiàn)程執(zhí)行,所以在多CPU下,ParNew效果通常會(huì)比Serial好。但如果是單CPU則會(huì)因?yàn)榫€(xiàn)程的切換,性能反而更差。

Parallel Scavenge收集器

新生代的收集器,同樣用的是復(fù)制算法,也是并行多線(xiàn)程收集。與ParNew最大的不同,它關(guān)注的是垃圾回收的吞吐量。

這里的吞吐量指的是 總時(shí)間與垃圾回收時(shí)間的比例。這個(gè)比例越高,證明垃圾回收占整個(gè)程序運(yùn)行的比例越小。

Parallel Scavenge收集器提供兩個(gè)參數(shù)控制垃圾回收的執(zhí)行:

-XX:MaxGCPauseMillis,最大垃圾回收停頓時(shí)間。這個(gè)參數(shù)的原理是空間換時(shí)間,收集器會(huì)控制新生代的區(qū)域大小,從而盡可能保證回收少于這個(gè)最大停頓時(shí)間。簡(jiǎn)單的說(shuō)就是回收的區(qū)域越小,那么耗費(fèi)的時(shí)間也越小。

所以這個(gè)參數(shù)并不是設(shè)置得越小越好。設(shè)太小的話(huà),新生代空間會(huì)太小,從而更頻繁的觸發(fā)GC。

-XX:GCTimeRatio,垃圾回收時(shí)間與總時(shí)間占比。這個(gè)是吞吐量的倒數(shù),原理和MaxGCPauseMillis相同。

因?yàn)镻arallel Scavenge收集器關(guān)注的是吞吐量,所以當(dāng)設(shè)置好以上參數(shù)的時(shí)候,同時(shí)不想設(shè)置各個(gè)區(qū)域大?。ㄐ律夏甏龋???梢蚤_(kāi)啟-XX:UseAdaptiveSizePolicy參數(shù),讓JVM監(jiān)控收集的性能,動(dòng)態(tài)調(diào)整這些區(qū)域大小參數(shù)。

Serial Old收集器

老年代的收集器,與Serial一樣是單線(xiàn)程,不同的是算法用的是標(biāo)記-整理(Mark-Compact)。

因?yàn)槔夏甏锩鎸?duì)象的存活率高,如果依舊是用復(fù)制算法,需要復(fù)制的內(nèi)容較多,性能較差。并且在極端情況下,當(dāng)存活為100%時(shí),沒(méi)有辦法用復(fù)制算法。所以需要用Mark-Compact,以有效地避免這些問(wèn)題。

Parallel Old收集器

老年代的收集器,是Parallel Scavenge老年代的版本。其中的算法替換成Mark-Compact。

CMS收集器

CMS,Concurrent Mark Sweep,同樣是老年代的收集器。它關(guān)注的是垃圾回收最短的停頓時(shí)間(低停頓),在老年代并不頻繁GC的場(chǎng)景下,是比較適用的。

命名中用的是concurrent,而不是parallel,說(shuō)明這個(gè)收集器是有與工作執(zhí)行并發(fā)的能力的。MS則說(shuō)明算法用的是Mark Sweep算法。

來(lái)看看具體地工作原理。CMS整個(gè)過(guò)程比之前的收集器要復(fù)雜,整個(gè)過(guò)程分為四步:

初始標(biāo)記(initial mark),單線(xiàn)程執(zhí)行,需要“Stop The World”,但僅僅把GC Roots的直接關(guān)聯(lián)可達(dá)的對(duì)象給標(biāo)記一下,由于直接關(guān)聯(lián)對(duì)象比較小,所以這里的速度非???。

并發(fā)標(biāo)記(concurrent mark),對(duì)于初始標(biāo)記過(guò)程所標(biāo)記的初始標(biāo)記對(duì)象,進(jìn)行并發(fā)追蹤標(biāo)記,此時(shí)其他線(xiàn)程仍可以繼續(xù)工作。此處時(shí)間較長(zhǎng),但不停頓。

重新標(biāo)記(remark),在并發(fā)標(biāo)記的過(guò)程中,由于可能還會(huì)產(chǎn)生新的垃圾,所以此時(shí)需要重新標(biāo)記新產(chǎn)生的垃圾。此處執(zhí)行并行標(biāo)記,與用戶(hù)線(xiàn)程不并發(fā),所以依然是“Stop The World”,時(shí)間比初始時(shí)間要長(zhǎng)一點(diǎn)。

并發(fā)清除(concurrent sweep),并發(fā)清除之前所標(biāo)記的垃圾。其他用戶(hù)線(xiàn)程仍可以工作,不需要停頓。


由于最耗費(fèi)時(shí)間的并發(fā)標(biāo)記與并發(fā)清除階段都不需要暫停工作,所以整體的回收是低停頓的。

由于CMS以上特性,缺點(diǎn)也是比較明顯的,

Mark Sweep算法會(huì)導(dǎo)致內(nèi)存碎片比較多

CMS的并發(fā)能力依賴(lài)于CPU資源,所以在CPU數(shù)少和CPU資源緊張的情況下,性能較差

并發(fā)清除階段,用戶(hù)線(xiàn)程依然在運(yùn)行,所以依然會(huì)產(chǎn)生新的垃圾,此階段的垃圾并不會(huì)再本次GC中回收,而放到下次。所以GC不能等待內(nèi)存耗盡的時(shí)候才進(jìn)行GC,這樣的話(huà)會(huì)導(dǎo)致并發(fā)清除的時(shí)候,用戶(hù)線(xiàn)程可以了利用的空間不足。所以這里會(huì)浪費(fèi)一些內(nèi)存空間給用戶(hù)線(xiàn)程預(yù)留。

有人會(huì)覺(jué)得既然Mark Sweep會(huì)造成內(nèi)存碎片,那么為什么不把算法換成Mark Compact呢?

答案其實(shí)很簡(jiǎn)答,因?yàn)楫?dāng)并發(fā)清除的時(shí)候,用Compact整理內(nèi)存的話(huà),原來(lái)的用戶(hù)線(xiàn)程使用的內(nèi)存還怎么用呢?要保證用戶(hù)線(xiàn)程能繼續(xù)執(zhí)行,前提的它運(yùn)行的資源不受影響嘛。Mark Compact更適合“Stop the World”這種場(chǎng)景下使用。

G1收集器

G1,Garbage First,在JDK 1.7版本正式啟用,是當(dāng)時(shí)最前沿的垃圾收集器。G1可以說(shuō)是CMS的終極改進(jìn)版,解決了CMS內(nèi)存碎片、更多的內(nèi)存空間登問(wèn)題。雖然流程與CMS比較相似,但底層的原理已是完全不同。

高效益優(yōu)先。G1會(huì)預(yù)測(cè)垃圾回收的停頓時(shí)間,原理是計(jì)算老年代對(duì)象的效益率,優(yōu)先回收最大效益的對(duì)象。

堆內(nèi)存結(jié)構(gòu)的不同。以前的收集器分代是劃分新生代、老年代、持久代等。

G1則是把內(nèi)存分為多個(gè)大小相同的區(qū)域Region,每個(gè)Region擁有各自的分代屬性,但這些分代不需要連續(xù)。

這樣的分區(qū)可以有效避免內(nèi)存碎片化問(wèn)題。

但是這樣同樣會(huì)引申一個(gè)新的問(wèn)題,就是分代的內(nèi)存不連續(xù),導(dǎo)致在GC搜索垃圾對(duì)象的時(shí)候需要全盤(pán)掃描找出引用內(nèi)存所在。

為了解決這個(gè)問(wèn)題,G1對(duì)于每個(gè)Region都維護(hù)一個(gè)Remembered Set,用于記錄對(duì)象引用的情況。當(dāng)GC發(fā)生的時(shí)候根據(jù)Remembered Set的引用情況去搜索。

兩種GC模式

Young GC,關(guān)注于所有年輕代的Region,通過(guò)控制收集年輕代的Region個(gè)數(shù),從而控制GC的回收時(shí)間。

Mixed GC,關(guān)注于所有年輕代的Region,并且加上通過(guò)預(yù)測(cè)計(jì)算最大收益的若干個(gè)老年代Region。

整體的執(zhí)行流程:

初始標(biāo)記(initial mark),標(biāo)記了從GC Root開(kāi)始直接關(guān)聯(lián)可達(dá)的對(duì)象。STW(Stop the World)執(zhí)行。

并發(fā)標(biāo)記(concurrent marking),并發(fā)標(biāo)記初始標(biāo)記的對(duì)象,此時(shí)用戶(hù)線(xiàn)程依然可以執(zhí)行。

最終標(biāo)記(Remark),STW,標(biāo)記再并發(fā)標(biāo)記過(guò)程中產(chǎn)生的垃圾。

篩選回收(Live Data Counting And Evacuation),評(píng)估標(biāo)記垃圾,根據(jù)GC模式回收垃圾。STW執(zhí)行。


在Region層面上,整體的算法偏向于Mark-Compact。因?yàn)槭荂ompact,會(huì)影響用戶(hù)線(xiàn)程執(zhí)行,所以回收階段需要STW執(zhí)行。

令人驚嘆的ZGC

在JDK 11當(dāng)中,加入了實(shí)驗(yàn)性質(zhì)的ZGC。它的回收耗時(shí)平均不到2毫秒。它是一款低停頓高并發(fā)的收集器。

ZGC幾乎在所有地方并發(fā)執(zhí)行的,除了初始標(biāo)記的是STW的。所以停頓時(shí)間幾乎就耗費(fèi)在初始標(biāo)記上,這部分的實(shí)際是非常少的。那么其他階段是怎么做到可以并發(fā)執(zhí)行的呢?

ZGC主要新增了兩項(xiàng)技術(shù),一個(gè)是著色指針Colored Pointer,另一個(gè)是讀屏障Load Barrier。

著色指針Colored Pointer
ZGC利用指針的64位中的幾位表示Finalizable、Remapped、Marked1、Marked0(ZGC僅支持64位平臺(tái)),以標(biāo)記該指向內(nèi)存的存儲(chǔ)狀態(tài)。相當(dāng)于在對(duì)象的指針上標(biāo)注了對(duì)象的信息。注意,這里的指針相當(dāng)于Java術(shù)語(yǔ)當(dāng)中的引用。

在這個(gè)被指向的內(nèi)存發(fā)生變化的時(shí)候(內(nèi)存在Compact被移動(dòng)時(shí)),顏色就會(huì)發(fā)生變化。

在G1的時(shí)候就說(shuō)到過(guò),Compact階段是需要STW,否則會(huì)影響用戶(hù)線(xiàn)程執(zhí)行。那么怎么解決這個(gè)問(wèn)題呢?

讀屏障Load Barrier
由于著色指針的存在,在程序運(yùn)行時(shí)訪(fǎng)問(wèn)對(duì)象的時(shí)候,可以輕易知道對(duì)象在內(nèi)存的存儲(chǔ)狀態(tài)(通過(guò)指針訪(fǎng)問(wèn)對(duì)象),若請(qǐng)求讀的內(nèi)存在被著色了。那么則會(huì)觸發(fā)讀屏障。讀屏障會(huì)更新指針再返回結(jié)果,此過(guò)程有一定的耗費(fèi),從而達(dá)到與用戶(hù)線(xiàn)程并發(fā)的效果。

把這兩項(xiàng)技術(shù)聯(lián)合下理解,引用R大(RednaxelaFX)的話(huà)

與標(biāo)記對(duì)象的傳統(tǒng)算法相比,ZGC在指針上做標(biāo)記,在訪(fǎng)問(wèn)指針時(shí)加入Load Barrier(讀屏障),比如當(dāng)對(duì)象正被GC移動(dòng),指針上的顏色就會(huì)不對(duì),這個(gè)屏障就會(huì)先把指針更新為有效地址再返回,也就是,永遠(yuǎn)只有單個(gè)對(duì)象讀取時(shí)有概率被減速,而不存在為了保持應(yīng)用與GC一致而粗暴整體的Stop The World。

ZGC雖然目前還在JDK 11還在實(shí)驗(yàn)階段,但由于算法與思想是一個(gè)非常大的提升,相信在未來(lái)不久會(huì)成為主流的GC收集器使用。

更多技術(shù)文章、精彩干貨,請(qǐng)關(guān)注
博客:zackku.com
微信公眾號(hào):Zack說(shuō)碼

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/77310.html

相關(guān)文章

  • 一文了解JVM

    摘要:而使用虛擬機(jī)是實(shí)現(xiàn)這一特點(diǎn)的關(guān)鍵。每個(gè)字節(jié)碼指令都由一個(gè)字節(jié)的操作碼和附加的操作數(shù)組成。字節(jié)碼可以通過(guò)以下兩種方式轉(zhuǎn)換成合適的語(yǔ)言解釋器一條一條地讀取,解釋并執(zhí)行字節(jié)碼執(zhí)行,所以它可以很快地解釋字節(jié)碼,但是執(zhí)行起來(lái)會(huì)比較慢。 一、什么是JVM JVM是Java Virtual Machine(Java 虛擬機(jī))的縮寫(xiě),JVM是一種用于計(jì)算設(shè)備的規(guī)范,它是一個(gè)虛構(gòu)出來(lái)的計(jì)算機(jī),是通過(guò)在實(shí)...

    whatsns 評(píng)論0 收藏0
  • JVM(2)--一文讀懂垃圾回收

    摘要:對(duì)象存不進(jìn)去,會(huì)又一次觸發(fā)垃圾回收。也就是說(shuō),它在進(jìn)行垃圾回收時(shí),必須暫停其他所有線(xiàn)程。我們來(lái)看一個(gè)名詞吞吐量。吞吐量運(yùn)行用戶(hù)代碼時(shí)間運(yùn)行用戶(hù)代碼時(shí)間垃圾收集時(shí)間。也就是說(shuō),收集器會(huì)嚴(yán)格控制吞吐量,至于這個(gè)吞吐量是多少,這個(gè)可以人為設(shè)置。 與其他語(yǔ)言相比,例如c/c++,我們都知道,java虛擬機(jī)對(duì)于程序中產(chǎn)生的垃圾,虛擬機(jī)是會(huì)自動(dòng)幫我們進(jìn)行清除管理的,而像c/c++這些語(yǔ)言平臺(tái)則需要...

    MRZYD 評(píng)論0 收藏0
  • Java基礎(chǔ)篇——JVM之GC原理(干貨滿(mǎn)滿(mǎn))

    摘要:此外,從結(jié)果我們可以得知,一個(gè)堆對(duì)象的放在局部變量表中的第一項(xiàng)引用會(huì)永遠(yuǎn)存在,在方法體內(nèi)可以將引用賦值給其他變量,這樣堆中對(duì)象就可以被其他變量所引用,即不會(huì)被回收。 原創(chuàng)不易,如需轉(zhuǎn)載,請(qǐng)注明出處https://www.cnblogs.com/baixianlong/p/10697554.html,多多支持哈! 一、什么是GC? GC是垃圾收集的意思,內(nèi)存處理是編程人員容易出現(xiàn)問(wèn)題的地...

    liaorio 評(píng)論0 收藏0
  • 細(xì)述 Java垃圾回收機(jī)制→Types of Java Garbage Collectors

    摘要:并發(fā)標(biāo)記清除垃圾回收器,使用多個(gè)線(xiàn)程來(lái)掃描堆內(nèi)存并標(biāo)記可被清除的對(duì)象,然后清除標(biāo)記的對(duì)象。垃圾回收器應(yīng)用于大的堆內(nèi)存空間。它將堆內(nèi)存空間劃分為不同的區(qū)域,對(duì)各個(gè)區(qū)域并行地做回收工作。它會(huì)通過(guò)把重復(fù)的值移動(dòng)到同一個(gè)數(shù)組來(lái)優(yōu)化堆內(nèi)存占用。 本文非原創(chuàng),翻譯自Types of Java Garbage Collectors在Java中為對(duì)象分配和釋放內(nèi)存空間都是由垃圾回收線(xiàn)程自動(dòng)執(zhí)行完成的。...

    Julylovin 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<