一、垃圾回收器分類
新生代垃圾收集器:Serial 、 ParNew 、Parallel Scavenge
老年代垃圾收集器:Serial Old 、 Parallel Old 狸吞、CMS
整理收集器:G1
垃圾回收器組合關(guān)系
- JDK7、8中默認(rèn)使用組合是: Parallel Scavenge GC 指煎、ParallelOld GC
- JDK9默認(rèn)使用G1為垃圾收集器
- JDK14 棄用了: Parallel Scavenge GC 蹋偏、Parallel OldGC;移除了 CMS GC
GC性能指標(biāo)
- 吞吐量:即CPU用于運(yùn)行用戶代碼的時(shí)間與CPU總消耗時(shí)間的比值(吞吐量 = 運(yùn)行用戶代碼時(shí)間 / ( 運(yùn)行用戶代碼時(shí)間 + 垃圾收集時(shí)間 ))至壤。例如:虛擬機(jī)共運(yùn)行100分鐘威始,垃圾收集器花掉1鐘,那么吞吐量就是99%
- 暫停時(shí)間:執(zhí)行垃圾回收時(shí)像街,程序的工作線程被暫停的時(shí)間
二黎棠、Serial垃圾收集器
串行。針對(duì)新生代镰绎;采用標(biāo)記-復(fù)制算法脓斩; 進(jìn)行垃圾收集時(shí),必須暫停所有工作線程畴栖,直到完成随静;
- 使用方式:-XX:+UseSerialGC
三、ParNew垃圾收集器
并發(fā)吗讶。針對(duì)新生代燎猛;采用標(biāo)記-復(fù)制算法。ParNew收集器實(shí)質(zhì)上是Serial收集器的多線程并行版本照皆, 除了同時(shí)使用多條線程進(jìn)行垃圾收集之外都一樣重绷。
- 使用方式: 使用方式:-XX:+UseParNewGC
四、Parallel Scavenge垃圾收集器
并行(單核無并行)纵寝。新生代收集器论寨;采用標(biāo)記-復(fù)制算法。是1.8中默認(rèn)的收集器爽茴;吞吐量優(yōu)先葬凳。
特點(diǎn)
- Parallel Scavenge收集器的目標(biāo)是達(dá)到一個(gè)可控制的吞吐量(Throughput);
吞吐量=運(yùn)行用戶代碼時(shí)間/(運(yùn)行用戶代碼時(shí)間+垃圾收集時(shí)間) (虛擬機(jī)總共運(yùn)行100分鐘室奏,垃圾收集時(shí)間為1分鐘火焰,那么吞吐量就是99%) - 自適應(yīng)調(diào)節(jié)策略,自動(dòng)指定年輕代、Eden胧沫、Suvisor區(qū)的比例昌简。
適用場景
適合后臺(tái)運(yùn)算,交互不多的任務(wù)绒怨,如批量處理纯赎,訂單處理,科學(xué)計(jì)算等南蹂。
在學(xué)生端的論壇項(xiàng)目中使用這種垃圾收集器犬金,其項(xiàng)目訪問刷新頻率較低,但是有
很多后臺(tái)定時(shí)的計(jì)算任務(wù)六剥,適合使用這種垃圾收集器
參數(shù)設(shè)置:
使用方式:-XX:+UseParallelGC
吞吐量大小-XX:GCTimeRatio
-XX: GCTimeRatio參數(shù)的值則應(yīng)當(dāng)是一個(gè)大于0小于100的整數(shù)晚顷, 也就是垃圾收集時(shí)間占總時(shí)
間的 比率, 相當(dāng)于吞吐量的倒數(shù)疗疟。 假設(shè)GCTimeRatio的值為n该默,那么系統(tǒng)將花費(fèi)不超過1/(1+n)
的時(shí)間用于垃圾收集。譬如把此 參數(shù)設(shè)置為19策彤, 那允許的最大垃圾收集時(shí)間就占總時(shí)間的5%
(即1/(1+19)) 栓袖, 默認(rèn)值為99, 即允許最大1%(即 1/(1+99)) 的垃圾收集時(shí)間
最大垃圾收集停頓時(shí)間:-XX:MaxGCPauseMillis
-XX: MaxGCPauseMillis參數(shù)允許的值是一個(gè)大于0的毫秒數(shù)店诗, 收集器將盡力保證內(nèi)存回收
花費(fèi)的 時(shí)間不超過用戶設(shè)定值叽赊。 不過大家不要異想天開地認(rèn)為如果把這個(gè)參數(shù)的值設(shè)置得更
小一點(diǎn)就能使得 系統(tǒng)的垃圾收集速度變得更快, 垃圾收集停頓時(shí)間縮短是以犧牲吞吐量和新
生代空間為代價(jià)換取的: 系統(tǒng)把新生代調(diào)得小一些必搞, 收集300MB新生代肯定比收集500MB
快必指, 但這也直接導(dǎo)致垃圾收集發(fā)生得 更頻繁, 原來10秒收集一次恕洲、 每次停頓100毫秒塔橡,
現(xiàn)在變成5秒收集一次、 每次停頓70毫秒霜第。 停頓時(shí)間 的確在下降葛家, 但吞吐量也降下來了。
五泌类、 Serial Old垃圾收集器
串行癞谒。針對(duì)老年代;采用標(biāo)記-整理算法;
使用方式:-XX:+UseSerialGC
六弹砚、 Parallel Old垃圾收集器
并行双仍。是Parallel Scavenge收集器的老年代版本, 支持多線程并發(fā)收集桌吃, 基于標(biāo)記-整理算法實(shí)現(xiàn)朱沃。
應(yīng)用場景
- JDK1.6及之后用來代替老年代的Serial Old收集器;
- 特別是在Server模式茅诱,多CPU的情況下逗物;
- 這樣在注重吞吐量以及CPU資源敏感的場景,就有了Parallel Scavenge加Parallel Old收集器的"給力"應(yīng)用組合瑟俭;
七翎卓、CMS 垃圾收集器
并發(fā)。老年代的垃圾回收器摆寄。是以獲取最短垃圾收集停頓時(shí)間為目標(biāo)的收集器莲祸。使用的算法是標(biāo)記-清除算法
適用場景
目前很大一部分的java應(yīng)用幾種在互聯(lián)網(wǎng)的B/S系統(tǒng)服務(wù)器上,這類應(yīng)用尤其注重服務(wù)器的響應(yīng)速度椭迎,系統(tǒng)停頓時(shí)間最短锐帜,給用戶帶來良好的體驗(yàn)。
在管理端和學(xué)生端的交互性比較強(qiáng)的項(xiàng)目中可以使用這種垃圾回收
參數(shù)設(shè)置:XX:+UseConcMarkSweepGC
收集過程
1) 初始標(biāo)記
2) 并發(fā)標(biāo)記
3) 重新標(biāo)記
4) 并發(fā)清除
- 初始標(biāo)記(Initial-Mark)階段:這個(gè)階段程序所有的工作線程都將會(huì)因?yàn)?Stop-the-Wold"機(jī)制
而出現(xiàn)短暫的的暫停,這個(gè)階段的主要任務(wù)標(biāo)記處GC Roots 能夠關(guān)聯(lián)到的對(duì)象.一旦標(biāo)記完成后
就恢復(fù)之前被暫停的的所有應(yīng)用畜号。 由于直接關(guān)聯(lián)對(duì)象比較小缴阎,所以這里的操作速度非常快简软。
- 并發(fā)標(biāo)記(Concurrent-Mark)階段:從GC Roots的直接關(guān)聯(lián)對(duì)象開始遍歷整個(gè)對(duì)象圖的過程,
這個(gè)過程耗時(shí)較長,但是不需要暫停用戶線程, 用戶線程可以與垃圾回收器一起運(yùn)行蛮拔。
- 重新標(biāo)記(Remark)階段:由于并發(fā)標(biāo)記階段,程序的工作線程會(huì)和垃圾收集線程同時(shí)運(yùn)行
或者交叉運(yùn)行痹升,因此建炫,為了修正并發(fā)標(biāo)記期間因?yàn)橛脩衾^續(xù)運(yùn)行而導(dǎo)致標(biāo)記產(chǎn)生變動(dòng)的那一
部分對(duì)象的標(biāo)記記錄,這個(gè)階段的停頓時(shí)間通常比初始標(biāo)記階段長一些疼蛾,但也遠(yuǎn)比并發(fā)標(biāo)記
階段時(shí)間短肛跌。
- 清除并發(fā)(Concurrent-Sweep)階段: 此階段清理刪除掉標(biāo)記判斷已經(jīng)死亡的對(duì)象,并釋放
內(nèi)存空間。由于不需要移動(dòng)存活對(duì)象察郁,所以這個(gè)階段可以與用戶線程同時(shí)并發(fā)運(yùn)行衍慎。
三色標(biāo)記
- 白色:尚未訪問過。
- 黑色:本對(duì)象已訪問過皮钠,而且本對(duì)象 引用到 的其他對(duì)象 也全部訪問過了稳捆。
- 灰色:本對(duì)象已訪問過,但是本對(duì)象 引用到 的其他對(duì)象尚未全部訪問完麦轰。全部訪問后乔夯,會(huì)轉(zhuǎn)換為黑色砖织。
注意:在并發(fā)標(biāo)記的時(shí)候可能會(huì)出現(xiàn)多標(biāo)和漏標(biāo)的情況,多標(biāo)會(huì)產(chǎn)生浮動(dòng)垃圾末荐,漏標(biāo)會(huì)將引用中
的對(duì)象清除會(huì)導(dǎo)致程序出錯(cuò)侧纯,需要在重新標(biāo)記的時(shí)候(會(huì)stop the world)做出修改防止這種情況出現(xiàn)
缺點(diǎn)
1.CMS收集器對(duì)CPU資源非常敏感。在并發(fā)階段鞠评,它雖然不會(huì)導(dǎo)致用戶線程停頓茂蚓,但是會(huì)因?yàn)檎加煤攫摹⒘艘徊糠志€程而導(dǎo)致應(yīng)用程序變慢剃幌,總吞吐量會(huì)降低。是當(dāng)處理器核心數(shù)量不足四個(gè)時(shí)晾浴, CMS對(duì)用戶程序的影響就可能變得很大负乡。
2.CMS收集器無法處理浮動(dòng)垃圾,可能出現(xiàn)"Concurrent Mode Failure"失敗而導(dǎo)致另一次Full GC的產(chǎn)生脊凰。
3.空間碎片:CMS是一款基于標(biāo)記-清除算法實(shí)現(xiàn)的收集器抖棘,所有會(huì)有空間碎片的現(xiàn)象
concurrent mode failure是什么?
CMS垃圾收集器特有的錯(cuò)誤狸涌,CMS的垃圾清理和引用線程是并行進(jìn)行的切省,如果在并行清理的過程中老年代的空間不足以容納應(yīng)用產(chǎn)生的垃圾(也就是老年代正在清理,從年輕代晉升了新的對(duì)象帕胆,或者直接分配大對(duì)象年輕代放不下導(dǎo)致直接在老年代生成朝捆,這時(shí)候老年代也放不下),則會(huì)拋出“concurrent mode failure”懒豹。
八芙盘、G1垃圾收集器
Garbage First是一款面向服務(wù)端應(yīng)用的垃圾收集器,主要針對(duì)配備多核CPU及大容量內(nèi)存的機(jī)器脸秽,以極高概率滿足GC停頓時(shí)間的同時(shí)儒老,還兼具高吞吐量的性能特征。
G1收集器特點(diǎn)
- G1把內(nèi)存劃分為多個(gè)獨(dú)立的區(qū)域Region
- G1仍然保留分代思想,保留了新生代和老年代,但他們不再是物理隔離,而是一部分Region的集合
- G1能夠充分利用多CPU记餐、多核環(huán)境硬件優(yōu)勢(shì)驮樊,盡量縮短STW
- G1整體整體采用標(biāo)記整理算法,局部是采用復(fù)制算法,不會(huì)產(chǎn)生內(nèi)存碎片
- G1的停頓可預(yù)測(cè),能夠明確指定在一個(gè)時(shí)間段內(nèi),消耗在垃圾收集上的時(shí)間不超過設(shè)置時(shí)間
- G1跟蹤各個(gè)Region里面垃圾的價(jià)值大小,會(huì)維護(hù)一個(gè)優(yōu)先列表,每次根據(jù)允許的時(shí)間來回收價(jià)值最大的區(qū)域,從而保證在有限事件內(nèi)高效的收集垃圾
Region
G1不再堅(jiān)持固定大小以及固定數(shù)量的 分代區(qū)域劃分, 而是把連續(xù)的Java堆劃分為多個(gè)獨(dú)立區(qū)域(Region) 片酝, 每一個(gè)Region都可以根據(jù)需要巩剖, 扮演新生代的Eden空間、 Survivor空間钠怯, 或者老年代空間佳魔。Region是G1回收器一次回收的最小單元。即每一次回收都是回收N個(gè)Region晦炊。
將整個(gè)堆空間細(xì)分為若干個(gè)小的區(qū)域宁脊。
- ①使用G1收集器時(shí),它將整個(gè)Java堆劃分成約2048個(gè)大小相同的獨(dú)立Region塊贤姆,每個(gè)Region塊大小根據(jù)堆空間的實(shí)際大小而定,為2的N次冪霞捡,即1MB, 2MB, 4MB, 8MB, 16MB,32MB。
- ② 雖然還保留有新生代和老年代的概念赊琳,但新生代和老年代不再是物理隔離的了,它們都是一部分Region (不需要連續(xù))的集合。通過Region的動(dòng)態(tài)分配方式實(shí)現(xiàn)邏輯上的連續(xù)趁尼。
- ③ G1垃圾收集器還增加了一種新的內(nèi)存區(qū)域,叫做Humongous內(nèi)存區(qū)域猖辫,如圖中的H塊啃憎。主要用于存儲(chǔ)大對(duì)象芝囤,如果超過1 .5個(gè)region,就放到H。一般被視為老年代.
卡片 Card
在每個(gè)分區(qū)內(nèi)部又被分成了若干大小為512 Byte卡片(Card)荧飞,標(biāo)識(shí)堆內(nèi)存最小可用粒度所有分區(qū)的卡片將會(huì)記錄在全局卡片表(Global Card Table)中凡人,分配的對(duì)象會(huì)占用物理上連續(xù)的若干個(gè)卡片,當(dāng)查找對(duì)分區(qū)內(nèi)對(duì)象的引用時(shí)便可通過記錄卡片來查找該引用對(duì)象(見RSet)叹阔。每次對(duì)內(nèi)存的回收挠轴,都是對(duì)指定分區(qū)的卡片進(jìn)行處理。
G1對(duì)內(nèi)存的使用以分區(qū)(Region)為單位耳幢,而對(duì)對(duì)象的分配則以卡片(Card)為單位岸晦。
G1的gc過程
G1提供了兩種GC模式,Young GC和Mixed GC睛藻,兩種均是完全Stop The World的启上。
- Young GC:對(duì)年輕代的gc
- Mixed GC:對(duì)年輕代和老年的gc
在G1 GC垃圾回收的過程一個(gè)有四個(gè)階段:
- 初始標(biāo)記 :和CMS一樣
只標(biāo)記GC Roots直接關(guān)聯(lián)的對(duì)象 - 并發(fā)標(biāo)記 :進(jìn)行GC Roots Traceing過程
- 最終標(biāo)記 :修正并發(fā)標(biāo)記期間,因程序運(yùn)行導(dǎo)致發(fā)生變化的那一部分對(duì)象
- 篩選回收 :根據(jù)時(shí)間來進(jìn)行價(jià)值最大化收集。把一部分region的活對(duì)象拷貝到空Region里面去店印,然后回收原本的Region空間冈在,該階段是STW(stop-the-world)的。整理堆分區(qū)按摘,為混合收集周期識(shí)別回收收益高(基于釋放空間和暫 停目標(biāo))的老年代分區(qū)集合包券;
隨著老年代內(nèi)存增長纫谅,當(dāng)?shù)竭_(dá)IHOP閾值-XX:InitiatingHeapOccupancyPercent(老年代占整堆比,默認(rèn)45%)時(shí)溅固,G1開始著手準(zhǔn)備收集老年代空間付秕。首先經(jīng)歷并發(fā)標(biāo)記周期,識(shí)別出高收益的老年代分區(qū)侍郭,前文已述询吴。但隨后G1并不會(huì)馬上開始一次混合收集,而是讓應(yīng)用線程先運(yùn)行一段時(shí)間亮元,等待觸發(fā)一次年輕代收集猛计。在這次STW中,G1將保準(zhǔn)整理混合收集周期苹粟。接著再次讓應(yīng)用線程運(yùn)行有滑,當(dāng)接下來的幾次年輕代收集時(shí)跃闹,將會(huì)有老年代分區(qū)加入到CSet中嵌削,即觸發(fā)混合收集,這些連續(xù)多次的混合收集稱為混合收集周期