掃二維碼與項(xiàng)目經(jīng)理溝通
我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營(yíng)咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
?大家好,我是樹哥。

創(chuàng)新互聯(lián)公司-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比項(xiàng)城網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫(kù),直接使用。一站式項(xiàng)城網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋項(xiàng)城地區(qū)。費(fèi)用合理售后完善,十年實(shí)體公司更值得信賴。
之前我們聊過 CMS 回收器,但那時(shí)候我們說 CMS 回收器已經(jīng)落伍了,現(xiàn)在應(yīng)該是用 G1 回收器的時(shí)候了。那么 G1 回收器到底有什么魔力,它比 CMS 回收器相比強(qiáng)在哪里呢?今天,就讓樹哥帶大家盤一盤!
文章思維導(dǎo)圖
G1(Garbage-First)回收器早在 JDK1.7 的時(shí)候就確定要做,但直到 JDK7u4 的時(shí)候才正式推出使用。等到了 JDK9 之后變成了默認(rèn)的垃圾回收器,同時(shí)廢棄了 CMS 回收器。
G1 回收器是一款面向服務(wù)端應(yīng)用的垃圾回收器,它的長(zhǎng)期使命是替換 CMS 回收器。G1 回收器于 CMS 回收器相比,它們有相似的地方,例如:都是關(guān)注 GC 停頓時(shí)間的回收器,都采用了分代回收的思想。
但從整體的實(shí)現(xiàn)上來看,G1 回收器做了非常多的改進(jìn),可以說是對(duì) CMS 回收器的全面改進(jìn)。相對(duì)于 CMS 回收器來說,G1 回收器有下面幾個(gè)不同的地方:
對(duì)于 CMS 及之前的回收器來說,其 JVM 內(nèi)存空間按照分代的思路劃分成物理連續(xù)的一大片區(qū)域,如下圖所示。
但在 G1 回收器中,雖然也采用了分代的思路,但其并沒有為其分配一塊連續(xù)的內(nèi)存,而是將整塊內(nèi)存化整為零拆分成一個(gè)個(gè) Region,如下圖所示。
正如上圖所示,G1 回收器不再為年輕代和老年代劃分大塊的內(nèi)存,而是劃分成了一個(gè)個(gè)的 Region,每個(gè) Region 被標(biāo)記成年輕代或者老年代。在 G1 中,還多了一個(gè) Humongous 區(qū)域,其是為了優(yōu)化大對(duì)象的分配而誕生的。
G1 回收器化整為零的 Region 設(shè)計(jì)思想,是 G1 回收器比 CMS 回收器強(qiáng)大的核心。 通過將大塊的內(nèi)存化整為零,G1 回收器能夠更加靈活地控制 GC 停頓時(shí)間,并且也解決了 CMS 回收器存在的內(nèi)存碎片問題以及大內(nèi)存下的長(zhǎng) GC 停頓時(shí)間問題。
G1 回收器與 CMS 回收器的另一個(gè)很大的區(qū)別是:G1 回收器使用的是「標(biāo)記 - 整理」算法,而 CMS 回收器使用的是「標(biāo)記 - 清除」算法。 因此,CMS 回收器會(huì)產(chǎn)生非常多的內(nèi)存碎片,而 G1 回收器則沒有這個(gè)困擾。
有些小伙伴會(huì)問:那為什么 CMS 回收器不用「標(biāo)記 - 整理」算法呢?
很簡(jiǎn)單,因?yàn)?CMS 回收器的老年代很大,使用「標(biāo)記 - 整理」算法需要耗費(fèi)很長(zhǎng)的 GC 停頓時(shí)間,這會(huì)導(dǎo)致接口響應(yīng)時(shí)間變長(zhǎng)。實(shí)際上 CMS 回收器后續(xù)提供了 -XX:+UseCMSCompactAtFullCollection 參數(shù)去實(shí)現(xiàn)內(nèi)存壓縮,但在內(nèi)存壓縮的時(shí)候 GC 停頓時(shí)間會(huì)很長(zhǎng),從而導(dǎo)致接口響應(yīng)時(shí)間變長(zhǎng)。
好奇寶寶又問了:G1 回收器也用的是「標(biāo)記 - 整理」算法,為啥就不會(huì)導(dǎo)致長(zhǎng) GC 停頓時(shí)間呢?
很簡(jiǎn)單,因?yàn)?G1 回收器使用了分 Region 的思想,其將大塊的內(nèi)存化整為零成為 Region。此外,其還維護(hù)了一個(gè)待回收 Region 列表,可以選擇回收性價(jià)比最高的 Region 進(jìn)行回收,從而實(shí)現(xiàn)對(duì) GC 停頓時(shí)間的靈活控制。
看到了么,G1 回收器化整為零的 Region 設(shè)計(jì)思想,真的是 G1 回收器的大殺器!
G1 回收器對(duì)于 CMS 而言還有一個(gè)很大的優(yōu)勢(shì),即能建立可預(yù)測(cè)的停頓時(shí)間模型,能讓使用者明確指定在一個(gè)長(zhǎng)度為 M 毫秒的時(shí)間片段內(nèi),消耗在垃圾收集上的時(shí)間不得超過 N 毫秒。對(duì)于該特性現(xiàn)在還用得比較少,大家了解一下就可以了。
比起 CMS 回收器來說,G1 回收器的垃圾回收過程就比較特別了,其采用了「年輕代收集」和「混合收集」兩種垃圾回收方式。
在應(yīng)用剛剛啟動(dòng)的時(shí)候,流量慢慢進(jìn)來,JVM 開始生成對(duì)象。G1 會(huì)選擇一個(gè)分區(qū)并指定 eden 分區(qū),當(dāng)這塊分區(qū)用滿之后,G1 會(huì)選一個(gè)新的分區(qū)作為 eden 分區(qū)。這個(gè)操作會(huì)一直進(jìn)行下去,一直到達(dá)到 eden 分區(qū)的上限,接著觸發(fā)一次年輕代收集。
年代收集采用的是「復(fù)制算法」,其首先使用單 eden、雙 survivor 遷移存活對(duì)象。在遷移過程中,會(huì)根據(jù)對(duì)象年齡以及其他特性,將對(duì)象晉升到老年代分區(qū)中,原有的年輕代分區(qū)會(huì)被整個(gè)回收掉。這個(gè)過程涉及到的規(guī)則和 CMS 回收器類似,只是 G1 回收器將內(nèi)存化整為零了而已。
隨著時(shí)間推移,越來越多的對(duì)象晉升到老年代中。當(dāng)老年代占比(占 Java 堆內(nèi)存的比例)達(dá)到 InitiatingHeapOccupancyPercent 參數(shù)之后,JVM 便會(huì)觸發(fā)「混合收集」進(jìn)行垃圾收集。要注意的是:混合收集會(huì)收集年輕代和部分老年代的內(nèi)存,其并不等同于 Full GC。Full GC 會(huì)回收整個(gè)老年代內(nèi)存。
對(duì)于混合收集方式來說,其收集過程可以分為 4 個(gè)階段:
初始標(biāo)記。 該階段與 CMS 回收器一樣,都只是簡(jiǎn)單標(biāo)記一下 GC Roots 能直接關(guān)聯(lián)到的對(duì)象,讓后續(xù) GC 回收線程能與用戶線程并發(fā)執(zhí)行。初始標(biāo)記階段是需要「Stop the World」的。
并發(fā)標(biāo)記。 該階段與 CMS 回收器一樣,它從 GC Root 開始對(duì)堆中對(duì)象進(jìn)行可達(dá)性分析,找出存活的對(duì)象,這階段耗時(shí)很長(zhǎng),但可與用戶程序并發(fā)執(zhí)行,不需要「Stop the World」。
最終標(biāo)記。 該階段與 CMS 回收器一樣,它是為了修正在并發(fā)標(biāo)記期間因用戶程序繼續(xù)運(yùn)作而導(dǎo)致引用發(fā)生變化的問題。只是 G1 回收器采用了不同的方式去實(shí)現(xiàn),在這個(gè)階段是需要「Stop the World」的。
篩選回收。 該階段與 CMS 回收器的并發(fā)清除一樣,它是去將標(biāo)記為垃圾的對(duì)象清除掉。只是對(duì)于 G1 回收器來說,它會(huì)維護(hù)各個(gè) Region 的回收價(jià)值和成本,隨后根據(jù)用戶期望的 GC 停頓時(shí)間來指定回收計(jì)劃。
來自《深入理解 Java 虛擬機(jī)》
整體看下來,我們會(huì)發(fā)現(xiàn) G1 回收器的混合收集過程與 CMS 回收器非常類似,都經(jīng)歷初始標(biāo)記、并發(fā)標(biāo)記、最終標(biāo)記、篩選回收(并發(fā)清除)幾個(gè)階段。
從 JDK7 正式推出到 JDK9 成為默認(rèn)的垃圾收集器,G1 回收器用了兩代人的時(shí)間打敗了 CMS 回收器。
從 G1 回收器的實(shí)現(xiàn)來看,其開創(chuàng)性的化整為零的 Region 設(shè)計(jì)思想,無疑是其打敗 CMS 回收器的秘訣。通過該設(shè)計(jì)思想,G1 回收器得以更加靈活地控制 GC 停頓時(shí)間,同時(shí)也可以實(shí)現(xiàn)更加高效、復(fù)雜的功能,例如:根據(jù)回收空間和耗時(shí)選擇最佳的回收 Region、預(yù)測(cè) GC 停頓時(shí)間等。

我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營(yíng)咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流