G1垃圾回收器

1偿警、背景

G1(Garbage First Collector 垃圾優(yōu)先的收集器)负间,說是一種全新的相艇,其實G1垃圾收集器已經(jīng)出現(xiàn)了N多年了颖杏,只是從發(fā)展到成熟是需要經(jīng)歷一定的過程,oracle官方計劃在jdk9中將G1變成默認的垃圾收集器坛芽,以替代CMS输玷, 可見G1肯定有它獨特的地方,它跟我們之前所學的各種垃圾底層是完全不一樣的靡馁,比如最明顯的不同是以前的分代收集方式是將堆劃分為新生代、老年代兩個區(qū)域机久,而新生代又劃分為Eden和兩個Survivor臭墨,也就是從物理的結(jié)構(gòu)就明確的做了區(qū)域劃分,但是1旄恰k食凇!G1它依據(jù)的物理形態(tài)跟我們之前所接觸的垃圾收集器完全不一樣了侠畔,也就是明顯會感覺到G1里面的堆內(nèi)存沒有明顯的區(qū)域劃分

2结缚、吞吐量:

  • 吞吐量關(guān)注的是,在一個指定的時間內(nèi)软棺,最大化一個應(yīng)用的工作量红竭。

  • 如下方式來衡量一個系統(tǒng)吞吐量的好壞:
    1、在一個小時內(nèi)同一個事務(wù)(或者任務(wù)喘落、請求)完成的次數(shù)(tps茵宪,實際中還會經(jīng)常見qps,每秒查詢率QPS是對一個特定的查詢服務(wù)器在規(guī)定時間內(nèi)所處理流量多少的衡量標準)瘦棋。
    2稀火、數(shù)據(jù)庫一小時可以完成多少次查詢。

  • 對于關(guān)注吞吐量的系統(tǒng)赌朋,卡頓是可以接受的凰狞,因為這個系統(tǒng)關(guān)注長時間的大量任務(wù)的執(zhí)行能力篇裁,單次快速的響應(yīng)并不值得考慮。

3赡若、響應(yīng)能力:

  • 響應(yīng)能力指一個程序或者系統(tǒng)對請求是否能夠及時響應(yīng)达布,比如:
    1、一個桌面UI能多快地響應(yīng)一個事件斩熊。
    2往枣、一個網(wǎng)站能夠多快返回一個頁面請求。
    3粉渠、數(shù)據(jù)庫能夠多快返回查詢的數(shù)據(jù)分冈。
  • 對于這類對響應(yīng)能力敏感的場景,長時間的停頓是無法接受的霸株。

以上是用來評價一個系統(tǒng)的兩個很重要的指標雕沉,介紹這兩個指標的原因是因為G1就是用來解決這樣的問題而應(yīng)運而生的。

4去件、G1垃圾回收器

  • g1收集器是一個面向服務(wù)端的垃圾收集器坡椒,適用于多核處理器、大內(nèi)存容量的服務(wù)端系統(tǒng)尤溜。
  • 它滿足短時間gc停頓的同時達到一個較高的吞吐量倔叼。
  • JDK7以上版本適用【通過配置JVM的參數(shù)來指定既可】。
    以上可以看到G1在吞吐量和響應(yīng)能力上都進行了兼顧宫莱。

5丈攒、G1收集器的設(shè)計目標:

(延遲可控的情況下獲得盡可能高的吞吐量)

  • 與應(yīng)用線程同時工作,幾乎【注意措辭】不需要stop the world(與CMS類似)授霸;
  • 整理剩余空間巡验,不產(chǎn)生內(nèi)存碎片(CMS只能在Full GC時,用stop the world整理內(nèi)存碎片)碘耳。
  • GC停頓更加可控显设;【要是CMS運行期間預留的內(nèi)存無法滿足程序需要時,虛擬機將啟動后備預案:臨時啟用Serial Old收集器來重新進行老年代的垃圾收集辛辨,這樣停頓時間就很長了捕捂。同時對于CMS來說如果出現(xiàn)了Full GC時,則會對新生代和老年代的堆內(nèi)存進行完整的整理愉阎,停頓時間就不可控了】
  • 不犧牲系統(tǒng)的吞吐量绞蹦;
  • gc不要求額外的內(nèi)存空間(CMS需要預留空間存儲浮動垃圾【這個在學習CMS中已經(jīng)闡述過了,其實就是CMS回收的過程跟用戶線程是并發(fā)進行的榜旦,所在在標記或者清除的同時對象的引用還會被改變幽七,使得原來對象本來不是垃圾,當CMS清理時該對象已經(jīng)變成了垃圾了溅呢,但是CMS認為它還不是垃圾澡屡,所以該對象的清除工作就會放到下一次了猿挚,所以將這種對象則稱之為浮動垃圾】

6、G1內(nèi)存模型

1驶鹉、G1堆結(jié)構(gòu)

image.png
image.png
(1)分區(qū) Region

G1 采用了分區(qū)(Region)的思路绩蜻,堆被劃分為一個個相等的不連續(xù)的內(nèi)存區(qū)域(regions),每個regions都有一個分代的角色:eden室埋、survivor办绝、old。對每個角色的數(shù)量并沒有強制的限定姚淆,也就是說對每種分代內(nèi)存的大小孕蝉,可以動態(tài)變化。每個分區(qū)也不會確定地為某個代服務(wù)腌逢,可以按需在年輕代和老年代之間切換降淮。啟動時可以通過參數(shù) -XX:G1HeapRegionSize=n 可指定分區(qū)大小(1MB~32MB搏讶,且必須是2的冪)佳鳖,默認將整堆劃分為2048個分區(qū)。

(2)卡片 Card

在每個分區(qū)內(nèi)部又被分成了若干個大小為512 Byte 卡片(Card)媒惕,標識堆內(nèi)存最小可用粒度所有分區(qū)的卡片將會記錄在全局卡片表(Global Card Table)中系吩,分配的對象會占用物理上連續(xù)的若干個卡片,當查找對分區(qū)內(nèi)對象的引用時便可通過記錄卡片來查找該引用對象(見 RSet)妒蔚。每次對內(nèi)存的回收淑玫,都是對指定分區(qū)的卡片進行處理。默認情況下面睛,每個卡都未被引用。當一個地址空間被引用時尊搬,這個地址空間對應(yīng)的數(shù)組索引的值被標記為“0”叁鉴,既標記為被引用,此外RSet也將這個數(shù)組下標記錄下來佛寿。一般情況下幌墓,這個RSet其實是一個Hash Table,key是當前Region的起始地址冀泻,Value是一個集合常侣,里面的元素是Card Table的Index。

(3)已記憶集合 Remember Set(RSet)

在串行和并行收集器中弹渔,GC 通過整堆掃描胳施,來確定對象是否處于可達路徑中。然而 G1 為了避免 STW 式的整堆掃描肢专,在每個分區(qū)記錄了一個已記憶集合(RSet)舞肆,內(nèi)部類似一個反向指針焦辅,記錄引用分區(qū)內(nèi)對象的卡片索引。當要回收該分區(qū)時椿胯,通過掃描分區(qū)的 RSet筷登,來確定引用本分區(qū)內(nèi)的對象是否存活,進而確定本分區(qū)內(nèi)的對象存活情況哩盲。

事實上前方,并非所有的引用都需要記錄在 RSet 中,引用源自本分區(qū)的對象廉油,當然不用落入 RSet 中惠险;同時,G1 GC 每次都會對年輕代進行整體收集娱两,因此引用源自年輕代的對象莺匠,也不需要在 RSet 中記錄。最后只有老年代的分區(qū)可能會有 RSet 記錄十兢,這些分區(qū)稱為擁有 RSet 分區(qū)(an RSet’s owning region)趣竣。

(4)Humongous區(qū)域

在G1中,還有一種特殊的區(qū)域旱物,叫Humongous區(qū)域遥缕。如果一個對象占用的空間達到或者超過了分區(qū)容量的50%以上,G1收集器就認為這是一個巨型對象宵呛。這些巨型對象单匣,默認直接會被分配在老年代,但是如果它是一個短期存在的巨型對象宝穗,就會對垃圾收集器造成負面影響户秤,為了解決這個問題,G1劃分 Humongous區(qū)域逮矛,它專門用來存放巨型對象鸡号。如果一個H區(qū)域裝不下一個巨型對象,那么G1會尋找連續(xù)的H分區(qū)來存儲须鼎。為了能找到連續(xù)的H區(qū)鲸伴,有時候不得不啟動Full GC

2、收集集合(CSet)

image.png

收集集合(CSet)代表每次 GC 暫停時回收的一系列目標分區(qū)晋控。在任意一次收集暫停中汞窗,CSet 所有分區(qū)都會被釋放,內(nèi)部存活的對象都會被轉(zhuǎn)移到分配的空閑分區(qū)中赡译。因此無論是年輕代收集仲吏,還是混合收集,工作的機制都是一致的。
①:年輕代收集 CSet 只容納年輕代分區(qū)蜘矢,
②:混合收集會通過某種算法狂男,在老年代候選回收分區(qū)中,篩選出回收收益最高的分區(qū)添加到 CSet 中品腹。
該算法是:G1跟蹤各個Region里面的垃圾堆積的價值大嗅场(回收所獲得的空間大小以及回收所需要時間的經(jīng)驗值),在后臺維護一個優(yōu)先列表舞吭,每次根據(jù)允許的收集時間泡垃,優(yōu)先回收價值最大的Region

年輕代收集集合 CSet of Young Collection(詳細版)

應(yīng)用線程不斷活動后,年輕代空間會被逐漸填滿羡鸥。當 JVM 分配對象到 Eden 區(qū)域失斆镅ā(Eden 區(qū)已滿)時,便會觸發(fā)一次 STW 式的年輕代收集惧浴。在年輕代收集中存和,Eden 分區(qū)存活的對象將被拷貝到 Survivor 分區(qū);原有 Survivor 分區(qū)存活的對象衷旅,將根據(jù)任期閾值(tenuring threshold)分別晉升到 PLAB 中捐腿,新的 survivor 分區(qū)和老年代分區(qū)。而原有的年輕代分區(qū)將被整體回收掉柿顶。

同時茄袖,年輕代收集還負責維護對象的年齡(存活次數(shù)),輔助判斷老化(tenuring)對象晉升的時候是到 Survivor 分區(qū)還是到老年代分區(qū)嘁锯。年輕代收集首先先將晉升對象尺寸總和宪祥、對象年齡信息維護到年齡表中,再根據(jù)年齡表家乘、Survivor 尺寸蝗羊、Survivor 填充容量 -XX:TargetSurvivorRatio(默認50%)、最大任期閾值 -XX:MaxTenuringThreshold(默認15)仁锯,計算出一個恰當?shù)娜纹陂撝抵饨唬彩浅^任期閾值的對象都會被晉升到老年代。

混合收集集合 CSet of Mixed Collection

年輕代收集不斷活動后扑馁,老年代的空間也會被逐漸填充。當老年代占用空間超過整堆比 IHOP 閾值 -XX:InitiatingHeapOccupancyPercent(默認45%)時凉驻,G1 就會啟動一次混合垃圾收集周期腻要。為了滿足暫停目標,G1 可能不能一口氣將所有的候選分區(qū)收集掉涝登,因此 G1 可能會產(chǎn)生連續(xù)多次的混合收集與應(yīng)用線程交替執(zhí)行雄家,每次 STW 的混合收集與年輕代收集過程相類似。

3胀滚、可預測的停頓模型

G1使用了gc停頓可預測的模型趟济,來滿足用戶設(shè)定的gc停頓時間乱投,根據(jù)用戶設(shè)定的目標時間,G1會自動地選擇哪些region要清除顷编,一次清除多少個region戚炫。

這是G1相對于CMS的另一個大優(yōu)勢,G1除了追求低停頓外媳纬,還能建立可預測的停頓時間模型双肤,能讓使用者明確指定在一個長度為M毫秒的時間片段內(nèi),消耗在垃圾收集上的時間不得超過N毫秒

  • 由于分區(qū)的原因钮惠,G1可以只選部分區(qū)域進行內(nèi)存回收茅糜,這樣縮小了回收的范圍,因此對于全局停頓情況的發(fā)生也能得到較好的控制
  • G1跟蹤各個Region里面的垃圾堆積的價值大兴赝臁(回收所獲得的空間大小以及回收所需要時間的經(jīng)驗值)蔑赘,在后臺維護一個優(yōu)先列表,每次根據(jù)允許的收集時間预明,優(yōu)先回收價值最大的Region缩赛。保證了G1收集器在有限的時間內(nèi)可以獲取盡可能高的收集效率。
  • 相比于CMS GC贮庞,G1未能做到CMS在最好情況下的延時停頓峦筒,但是最長情況要好很多
  • 停頓時間的設(shè)置并不是越短越好,設(shè)置的時間越短意味著每次收集的Cset越小窗慎,導致垃圾逐步積累變多物喷,最終不得不退化成Full GC(Serial GC),停頓時間設(shè)置過長遮斥,那么會導致每次都會產(chǎn)生長時間的停頓個峦失,影響了程序?qū)ν獾捻憫?yīng)時間

7、G1垃圾回收器的缺點

1术吗、相對于CMS尉辑,G1還不具備全方位、壓倒性的優(yōu)勢较屿,比如在用戶程序運行過程中隧魄,G1無論是為了垃圾收集產(chǎn)生的內(nèi)存占用還是程序運行時的額外執(zhí)行負載都要比CMS要高
2、從經(jīng)驗上來說隘蝎,在小內(nèi)存應(yīng)用上CMS的表現(xiàn)大概率會優(yōu)于G1购啄,而G1在大內(nèi)存應(yīng)用則發(fā)揮其優(yōu)勢,平衡點6 ~ 8GB之間

8嘱么、G1垃圾回收過程

1狮含、年輕代GC(Young GC)

年輕代垃圾回收只會回收Eden區(qū)和Survivor區(qū)。年輕代也使用了分區(qū)機制主要是因為便于代大小的調(diào)整

年輕代回收時,首先G1停止應(yīng)用程序的執(zhí)行(Stop - The - World)几迄,G1創(chuàng)建回收集(CSet)蔚龙,對于YGC來說,整個年輕代(Eden區(qū) + Survivor區(qū))都是CSet

然后開始如下回收過程(并行操作映胁,多個收集器的線程同時工作木羹,但是用戶線程處于等待狀態(tài)。)
階段1:根掃描

GC Roots包括
(1). 虛擬機棧(棧幀中的局部變量區(qū)屿愚,也叫做局部變量表)中引用的對象汇跨。
(2). 方法區(qū)中的類靜態(tài)屬性引用的對象。
(3). 方法區(qū)中常量引用的對象妆距。
(4). 本地方法棧中JNI(Native方法)引用的對象穷遂。

階段2:更新RSet

處理dirty card隊列更新RS(更新完后,RSet可以準確的反映老年代對所在的內(nèi)存分段中對象的引用)

對于應(yīng)用程序的引用賦值語句Object.field = object娱据,JVM會在之前和之后執(zhí)行特殊的操作以在dirty card queue中入隊一個保存了對象引用信息的card蚪黑。在年輕代回收的時候,G1會對DIrty Card Queue中所有的card進行處理中剩,以更新RSet忌穿,保證RSet實時準確的反映引用關(guān)系

那為什么不在引用賦值語句處直接更新RSet呢?這是為了性能的需要结啼,RSet的處理需要線程同步掠剑,開銷會很大,使用隊列性能會好很多

階段3:處理RSet

識別被老年代對象指向的Eden中的對象郊愧,這些被指向的Eden中的對象被認為存活的對象

階段4:復制對象

拷貝存活的對象到survivor/old區(qū)域朴译。① Survivor區(qū)內(nèi)存中存活的對象如果年齡未達到閾值,年齡會加1属铁,達到閾值會被賦值到Old區(qū)眠寿。 ② 如果Survivor空間不夠,Eden空間的部分數(shù)據(jù)會直接晉升到老年代空間

階段5:處理引用隊列

軟引用焦蘑、弱引用盯拱、虛引用處理

2、并發(fā)標記過程(Concurrent Marking)

1例嘱、初始標記(inital mark狡逢,STW):它標記了從GC Root開始直接可達的對象,并且會觸發(fā)一次年輕代的GC
2拼卵、根區(qū)域掃描(Root Region Sacnning):觸發(fā)的年輕代GC完成后奢浑,所有新復制到 Survivor 分區(qū)(根區(qū)域)的對象,都需要被掃描并標記成根间学,G1 GC掃描Survivor取直接可達的老年代區(qū)域?qū)ο螅擞洷灰玫膶ο蟆_@個過程必須在young GC之前完成
3低葫、并發(fā)標記(Concurrent Marking):這個階段從GC Root開始對heap中的對象進行標記详羡,標記線程與應(yīng)用程序線程并發(fā)執(zhí)行,并且收集各個Region的存活對象信息嘿悬。
4实柠、重新標記(Remark,STW):由于應(yīng)用程序持續(xù)進行善涨,需要修正上一次的標記結(jié)果窒盐,SATB算法
5、獨占清理(Exclusive Cleanup钢拧,STW):計算各個區(qū)域的存活對象和GC回收比例蟹漓,并進行排序,識別可以混合回收的區(qū)域源内。為混合回收做鋪墊葡粒,是STW的。這個階段不會實際上做垃圾的收集
6膜钓、并發(fā)清理(Concurrent Cleanup):清除空Region(沒有存活對象的)嗽交,加入到free list。

3颂斜、混合回收(Mixed GC)

在并發(fā)標記過程后進行拷貝存活對象

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末夫壁,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子沃疮,更是在濱河造成了極大的恐慌盒让,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件忿磅,死亡現(xiàn)場離奇詭異糯彬,居然都是意外死亡,警方通過查閱死者的電腦和手機葱她,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進店門撩扒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人吨些,你說我怎么就攤上這事搓谆。” “怎么了豪墅?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵泉手,是天一觀的道長。 經(jīng)常有香客問我偶器,道長斩萌,這世上最難降的妖魔是什么缝裤? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮颊郎,結(jié)果婚禮上憋飞,老公的妹妹穿的比我還像新娘。我一直安慰自己姆吭,他們只是感情好榛做,可當我...
    茶點故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著内狸,像睡著了一般检眯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上昆淡,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天锰瘸,我揣著相機與錄音,去河邊找鬼瘪撇。 笑死获茬,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼灼捂,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了佩谣?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤实蓬,失蹤者是張志新(化名)和其女友劉穎茸俭,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體安皱,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡调鬓,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了酌伊。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片腾窝。...
    茶點故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖居砖,靈堂內(nèi)的尸體忽然破棺而出虹脯,到底是詐尸還是另有隱情,我是刑警寧澤奏候,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布循集,位于F島的核電站,受9級特大地震影響蔗草,放射性物質(zhì)發(fā)生泄漏咒彤。R本人自食惡果不足惜疆柔,卻給世界環(huán)境...
    茶點故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望镶柱。 院中可真熱鬧婆硬,春花似錦、人聲如沸奸例。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽查吊。三九已至,卻和暖如春湖蜕,著一層夾襖步出監(jiān)牢的瞬間逻卖,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工昭抒, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留评也,地道東北人。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓灭返,卻偏偏與公主長得像盗迟,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子熙含,可洞房花燭夜當晚...
    茶點故事閱讀 45,077評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 目錄 基礎(chǔ)知識 G1回收流程 GC日志解析 線上參數(shù) 調(diào)優(yōu)案例 基礎(chǔ)知識 目的 G1 的主要關(guān)注點在于達到可控的停...
    后來丶_a24d閱讀 341評論 0 1
  • G1回收器: 區(qū)域分代化 既然我們已經(jīng)有了前面幾個強大的GC,為什么還要發(fā)布Garbage First(G1)GC...
    Shaw_Young閱讀 240評論 0 0
  • JVM提供了Serial收集器罚缕,Parallel收集器和CMS(Concurrent Mark-Sweep)并發(fā)標...
    zhglance閱讀 1,190評論 0 4
  • G1設(shè)計的目標是讓stop the world的時間是可預測和可配置的。C1垃圾回收器是軟實時怎静,低延遲的垃圾回收器...
    田美河邊的釣魚人閱讀 303評論 0 0
  • 在前一篇的文章《HotSpot垃圾回收算法概述》里面邮弹,對于Serial, Parallel和CMS幾種垃圾回收器做...
    flycash閱讀 73,169評論 21 80