垃圾回收器和原理(CMS悔醋、G1)

垃圾收集算法

  1. 標(biāo)記清除(會(huì)有內(nèi)存碎片,大對(duì)象時(shí)更有可能因?yàn)闆]有足夠的連續(xù)內(nèi)存而觸發(fā)GC芬骄,但是可以降低了STW的時(shí)間)

  2. 復(fù)制算法(優(yōu)點(diǎn)是沒有碎片,缺點(diǎn)是浪費(fèi)空間和復(fù)制過程中會(huì)STW,需要有專門的空白的內(nèi)存塊來存儲(chǔ)復(fù)制過來的對(duì)象姻僧,而且在復(fù)制的過程中需要STW撇贺。年輕代適合復(fù)制算法挎扰,默認(rèn)犧牲1/10的空間:Survivor to區(qū))遵倦,適合大部分都是垃圾的業(yè)務(wù)場(chǎng)景,年輕代棘脐。

  3. 標(biāo)記整理(或者也叫標(biāo)記壓縮蛀缝,避免了內(nèi)存碎片,同時(shí)也避免了復(fù)制算法的內(nèi)存空間浪費(fèi)在讶,但是壓縮的時(shí)候涉及到內(nèi)存地址的移動(dòng),此期間還是會(huì)STW)战坤,適合大部分都不是垃圾的業(yè)務(wù)場(chǎng)景碟嘴,老年代

  4. 分代回收:老年代和年輕代

其它細(xì)節(jié)

  1. 并發(fā)指的是同時(shí)發(fā)生栅组,比如一邊GC回收玉掸,一邊程序運(yùn)行排截,用戶行為不會(huì)受到影響断傲。并行指的是一個(gè)相同的操作同時(shí)多個(gè)線程來執(zhí)行箱蝠,比如ParNew多個(gè)線程同時(shí)進(jìn)行YGC宦搬。

  2. 垃圾收集器的搭配是有限定的矾克,不是任意都可以搭配。

垃圾回收器

年輕代回收器:Serial滓彰、Parallel Scanvenge、ParNew
老年代回收器:Serial Old菇存、Parallel Old、CMS
綜合回收器:G1

  1. Serial & Serial_Old 收集器
  • 分為年輕代Serial(復(fù)制算法) 和老年代的 Serial Old(標(biāo)記整理算法)
  • 串行回收,高效 穩(wěn)定但是stop the world較長(zhǎng)
  • 適合單核CPU关筒,效率高而且穩(wěn)定蒸播,避免了線程切換的開銷
  • 是Client模式下的默認(rèn)GC機(jī)制
  • Serial Old是CMS PromotionFailure后的默認(rèn)替代回收器
  1. ParNew回收器:CMS的最佳伴侶塘揣,因?yàn)镃MS只能和Serial和ParNew配合使用才写,而ParNew是多線程版本的Serial

  2. Parallel Scavenge回收器:多線程赞草,追求高吞吐量(運(yùn)行代碼時(shí)間/運(yùn)行代碼時(shí)間+GC時(shí)間) 和參數(shù)自動(dòng)調(diào)整

  • 支持配置GCMaxPause和GCTimeRatio兩個(gè)參數(shù)洲守,來控制GC最大停頓時(shí)間和吞吐量搭独,默認(rèn)99%
  • 支持配置UseAdaptiveSizePolicy牙肝,自動(dòng)調(diào)整年輕代 Eden、S0、S1區(qū)的大小和晉升老年代ratio敦姻,從而來滿足上面的兩個(gè)參數(shù)
  • 不能和CMS一起搭配使用,而和SerialOld搭配又浪費(fèi),所以一般都是和Parallel Old搭配使用
  1. Parallel Old:標(biāo)記整理茵瘾,吞吐量?jī)?yōu)先,追請(qǐng)的是性能最大化晨雳,比如一些后臺(tái)計(jì)算類突照,報(bào)表生成類的應(yīng)用

CMS收集器

適合多CPU座慰,頻繁和用戶交互的業(yè)務(wù)場(chǎng)景游盲,追求的是停頓時(shí)間最短,采用標(biāo)記清除的回收算法(因?yàn)闃?biāo)記清除不會(huì)涉及存活對(duì)象的移動(dòng):復(fù)制和壓縮,從而降低STW的時(shí)間)

回收4個(gè)階段

  1. 初始標(biāo)記:STW,快速獲取到老年代中的GC Roots對(duì)象令哟,以及遍歷新生代中GC Roots對(duì)象引用到老年代中的對(duì)象滑燃, 默認(rèn)是單線程執(zhí)行典予,也可以設(shè)置多線程數(shù)并行進(jìn)行捂敌。
  2. 并發(fā)標(biāo)記:并發(fā)客戶線程逆济,只分配一個(gè)線程來根據(jù)初始標(biāo)記里面的對(duì)象開始奖慌,逐個(gè)標(biāo)記 初始標(biāo)記成功的對(duì)象的引用的對(duì)象。如果并發(fā)期間,對(duì)象的引用關(guān)系發(fā)生改變蹦浦,則會(huì)被標(biāo)記為dirty對(duì)象盲镶。
  3. 重新標(biāo)記:STW溉贿,修正并發(fā)標(biāo)記期間浦旱,引用關(guān)系的改變,這個(gè)過程比初始標(biāo)記稍長(zhǎng)颁湖。
  4. 并發(fā)清除:專門分配一個(gè)線程來清除標(biāo)記過的對(duì)象甥捺,不影響用戶操作,此階段會(huì)有新的浮動(dòng)垃圾生成镰禾,如果太多唱逢,會(huì)造成PromotionFailure

CMS的缺點(diǎn)

  1. 對(duì)CPU資源敏感屋休,因?yàn)樵诓l(fā)標(biāo)記、并發(fā)清除的時(shí)候都需要占用一個(gè)單獨(dú)的線程來完成操作绸贡,如果CPU為2的話毅哗,那么就只有1個(gè)CPU能干活,一個(gè)CPU在GC
  2. 無法處理浮動(dòng)垃圾尿瞭,也就是每次GC都掃不干凈翅睛,因?yàn)椴l(fā)清除的過程中,還會(huì)有新的垃圾產(chǎn)生捕发,而且如果這個(gè)階段新的垃圾導(dǎo)致空間不足,會(huì)PromotionFailure
  3. 基于標(biāo)記清除算法會(huì)存在很多碎片檐涝,空間利用率不高法挨,需要配置壓縮參數(shù),但是在壓縮的過程中STW的時(shí)間會(huì)延長(zhǎng)

G1回收器

吞吐量和最短停頓時(shí)間本來就互相矛盾窃植,Parallel Old追求的是吞吐量荐糜,CMS追求的是STW的最短,而G1通過把堆分成多個(gè)相對(duì)獨(dú)立的Region塊暴氏,并行的進(jìn)行選擇性的回收偏序,實(shí)現(xiàn)一個(gè)兩者兼顧的回收器。

  1. G1類似于CMS研儒,G1回收器支持用戶并發(fā)操作独令,MajorGC在并發(fā)標(biāo)記時(shí)允許用戶線程同時(shí)進(jìn)行業(yè)務(wù)操作燃箭。

  2. G1相對(duì)CMS而言舍败,更加靈活,因?yàn)閮?nèi)部是多個(gè)Rigion組成邻薯,而且每個(gè)Rigion是獨(dú)立的(Rigion之間對(duì)象的相互引用記錄在Remembered Set里面),所以可以根據(jù)用戶設(shè)定的允許最長(zhǎng)停頓時(shí)間累榜,在一次MajorGC的過程中只回收部分Rigion(回收空間價(jià)值最高而經(jīng)驗(yàn)推算的時(shí)間成本又最低的Rigion塊灵嫌,比如Rigion1對(duì)象活躍度10%,Rigion2對(duì)象活躍度50%猖凛,那么優(yōu)先回收Rigion1塊)绪穆,這是CMS無法做到的,CMS的老年代是完整的一塊內(nèi)存,要GC的話量瓜,就必須整個(gè)老年代全部GC,而整個(gè)老年代全部GC的話扔傅,停頓的時(shí)間就會(huì)相對(duì)更長(zhǎng)烫饼。年輕代來看,也更加靈活杠纵,因?yàn)槟贻p代的Eden區(qū)和S區(qū)的Rigion塊數(shù)量是動(dòng)態(tài)調(diào)整的比藻。

  3. G1相對(duì)CMS而言倘屹,因?yàn)椴捎玫氖菑?fù)制算法慢叨,所以沒有內(nèi)存碎片的產(chǎn)生。避免了堆中大對(duì)象因?yàn)闆]有足夠的連續(xù)的內(nèi)存空間而觸發(fā)MajorGC的情況烛缔。其實(shí)CMS之所以使用標(biāo)記清除算法轩拨,是為了減少壓縮垃圾過程時(shí)的STW,因?yàn)镚1可以做到部分而不是所有Rigion塊的GC气嫁,所以可以在預(yù)測(cè)的時(shí)間內(nèi)完成復(fù)制操作。

  4. G1的適合大內(nèi)存的JVM環(huán)境崖面。因?yàn)椴捎脧?fù)制的算法(YGC和MajorGC都是復(fù)制)梯影,所以需要有一定的空閑內(nèi)存塊來存儲(chǔ)復(fù)制來的對(duì)象,空間利用率低。而且每次GC都不是完整的GC简识,需要該Region塊的活躍度低于一定標(biāo)準(zhǔn)感猛,這個(gè)Region塊才會(huì)發(fā)起回收,所以一些活躍度高的內(nèi)存塊里面的垃圾對(duì)象不會(huì)被回收掉,默認(rèn)堆內(nèi)存使用率達(dá)到45%的時(shí)候颈走,就開始FullGC咱士。

  5. G1適合多CPU的JVM環(huán)境。因?yàn)閭鹘y(tǒng)的回收器都是3個(gè)內(nèi)存塊序厉,而G1默認(rèn)是2000多個(gè)相對(duì)獨(dú)立的內(nèi)存塊弛房,在GC幾乎所有的過程中,Region塊都是高度并行化的進(jìn)行回收,而且還有在并發(fā)標(biāo)記階段支持用戶并發(fā)性的業(yè)務(wù)操作牺堰,所以對(duì)CPU的要求較高

  6. G1的靈活性還在于能夠根據(jù)設(shè)置的STW時(shí)間颅围,動(dòng)態(tài)調(diào)整各個(gè)分代的內(nèi)存占比,有點(diǎn)類似于Parallel Old筏养,但是和CMS是不同的常拓。

G1回收器FullGC回收過程

  1. 初始標(biāo)記,STW茎辐,分為老年代和年輕代兩部分掂恕。先會(huì)觸發(fā)一次YGC(排除掉年輕代對(duì)老年代有引用,但是該年輕代對(duì)象已經(jīng)死亡的情況)懊亡,然后再對(duì)Survivor to區(qū)進(jìn)行遍歷(確保所有的年輕代的對(duì)象都是活的店枣,因?yàn)榻?jīng)歷了一次YGC),查找并標(biāo)記S區(qū)對(duì)象對(duì)老年代的直接引用的所有老年代對(duì)象(這里是直接引用鸯两,比如Survivor to區(qū)A對(duì)象,引用了老年代的B對(duì)象忙灼,就標(biāo)記B對(duì)象逾柿,雖然B對(duì)象還可能引用了C宅此、D、E對(duì)象)弱匪。第二部分是針對(duì)老年代,標(biāo)記老年代中所有GC Roots直接引用的對(duì)象斥难。
  2. 并發(fā)標(biāo)記帘饶,根據(jù)可達(dá)性分析,找到所有GCRoots的對(duì)象引用及刻,一層一層的標(biāo)記,這個(gè)時(shí)候沒有STW暑劝,用戶線程正常執(zhí)行颗搂。
  3. 最終標(biāo)記,STW傅联,修正并發(fā)標(biāo)記期間的對(duì)象關(guān)系變更卖丸,根據(jù)Remembered Set Logs,來修改Remember Set载碌,該階段可以多個(gè)線程并行
  4. 篩選回收衅枫,STW,會(huì)跟蹤各個(gè)Rigion里面的垃圾堆積的價(jià)值大胁竭洹(比如需要回收的對(duì)象的空間大小以及回收所需時(shí)間的經(jīng)驗(yàn)值)排序,根據(jù)用戶設(shè)定的停頓時(shí)間益楼,回收特定Region,因?yàn)槊總€(gè)Region塊都有獨(dú)立的Remembered Set感凤,所以每個(gè)Region可以獨(dú)立的進(jìn)行回收陪竿,也就是多個(gè)Region塊并行多線程的垃圾回收。

G1回收的細(xì)節(jié)

  1. 當(dāng)執(zhí)行垃圾回收時(shí),G1以類似于CMS回收器的方式運(yùn)行锐墙。G1執(zhí)行一個(gè)并發(fā)的全局標(biāo)記階段长酗,以確定整個(gè)堆中對(duì)象的活躍度。
  2. G1使用一個(gè)暫停預(yù)測(cè)模型來滿足用戶定義的暫停時(shí)間目標(biāo)并基于指定的暫停時(shí)間目標(biāo)選擇回收的區(qū)域數(shù)量
  3. G1因?yàn)榻?jīng)常性的不完整GC刻盐,活躍度高的內(nèi)存塊GC的會(huì)更晚劳翰,而且需要有空閑的Region來實(shí)現(xiàn)復(fù)制,進(jìn)行垃圾回收的時(shí)機(jī)更早乙墙,默認(rèn)在堆內(nèi)存使用率達(dá)到45%時(shí)就會(huì)開始垃圾回收生均。這體現(xiàn)了G1(Garbage-First/垃圾回收優(yōu)先)這一名字的含義。至于活躍度多低才會(huì)進(jìn)行回收汉买,則是由G1決定的佩脊,G1會(huì)調(diào)整自己的回收策略來盡可能滿足用戶設(shè)置的最大STW時(shí)長(zhǎng)。
  4. 每個(gè)Rigion都有一個(gè)Remembered Set出牧,來紀(jì)錄Region塊之間的對(duì)象引用歇盼,RSet使得區(qū)域并行獨(dú)立的回收成為可能。當(dāng)程序發(fā)生寫操作的時(shí)候伯复,會(huì)判斷相關(guān)的引用是否涉及到跨Region的引用邢笙,比如Rigion0當(dāng)中,A對(duì)象之前是引用Rigion0中的B對(duì)象组底,現(xiàn)在執(zhí)行程序筐骇,A對(duì)象被重新賦值,引用了Rigion1中的C對(duì)象厌均,那么在Rigion1的Remembered Set當(dāng)中就要紀(jì)錄告唆,否則Region1在GC的時(shí)候,會(huì)把C對(duì)象直接回收了模她,通過讀取自己的Remembered Set知道C對(duì)象被Region0種的A對(duì)象引用懂牧,這樣既避免了全堆的掃描,又實(shí)現(xiàn)了分塊管理畜侦。
  5. FullGC觸發(fā)的時(shí)機(jī)是內(nèi)存使用率達(dá)到一定的比例躯保,默認(rèn)45%

G1中的年輕代,可以說明一下幾點(diǎn):

  • YGC觸發(fā)的條件是Eden區(qū)滿了
  • Survivor To塊可以認(rèn)為是一個(gè)空白塊验懊,因?yàn)閅GC和MajorGC都是采用復(fù)制算法盯孙,都是復(fù)制到一個(gè)空白的內(nèi)存塊當(dāng)中。
  • 年輕代垃圾回收使用多線程并行進(jìn)行歌溉,需要STW
  • 年輕代內(nèi)存由一組非連續(xù)的區(qū)域組成骑晶,而且Eden、S區(qū)的大小是動(dòng)態(tài)調(diào)整的
  • 存活對(duì)象被拷貝到新的幸存區(qū)或者年老代區(qū)域(超過存活ratio的對(duì)象進(jìn)入老年代)

參考資料

http://www.reibang.com/p/3cddf780c050

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末匙头,一起剝皮案震驚了整個(gè)濱河市仔雷,隨后出現(xiàn)的幾起案子舔示,更是在濱河造成了極大的恐慌惕稻,老刑警劉巖蝙叛,帶你破解...
    沈念sama閱讀 216,997評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異蜘渣,居然都是意外死亡肺然,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門捂龄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人加叁,你說我怎么就攤上這事倦沧。” “怎么了它匕?”我有些...
    開封第一講書人閱讀 163,359評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵展融,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我豫柬,道長(zhǎng)告希,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,309評(píng)論 1 292
  • 正文 為了忘掉前任烧给,我火速辦了婚禮燕偶,結(jié)果婚禮上础嫡,老公的妹妹穿的比我還像新娘指么。我一直安慰自己,他們只是感情好榴鼎,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,346評(píng)論 6 390
  • 文/花漫 我一把揭開白布伯诬。 她就那樣靜靜地躺著,像睡著了一般巫财。 火紅的嫁衣襯著肌膚如雪盗似。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,258評(píng)論 1 300
  • 那天平项,我揣著相機(jī)與錄音赫舒,去河邊找鬼悍及。 笑死,一個(gè)胖子當(dāng)著我的面吹牛接癌,可吹牛的內(nèi)容都是我干的并鸵。 我是一名探鬼主播,決...
    沈念sama閱讀 40,122評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼扔涧,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了届谈?” 一聲冷哼從身側(cè)響起枯夜,我...
    開封第一講書人閱讀 38,970評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎艰山,沒想到半個(gè)月后湖雹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,403評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡曙搬,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,596評(píng)論 3 334
  • 正文 我和宋清朗相戀三年摔吏,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片纵装。...
    茶點(diǎn)故事閱讀 39,769評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡征讲,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出橡娄,到底是詐尸還是另有隱情诗箍,我是刑警寧澤,帶...
    沈念sama閱讀 35,464評(píng)論 5 344
  • 正文 年R本政府宣布挽唉,位于F島的核電站滤祖,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏瓶籽。R本人自食惡果不足惜匠童,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,075評(píng)論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望塑顺。 院中可真熱鬧汤求,春花似錦、人聲如沸严拒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽糙俗。三九已至勒奇,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間巧骚,已是汗流浹背赊颠。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工格二, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人竣蹦。 一個(gè)月前我還...
    沈念sama閱讀 47,831評(píng)論 2 370
  • 正文 我出身青樓顶猜,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親痘括。 傳聞我的和親對(duì)象是個(gè)殘疾皇子长窄,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,678評(píng)論 2 354

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