
jvm的垃圾收集器分為如下幾種類型:
串行:Serial,Serial Old
吞吐量優(yōu)先: parNew, parallel Scavenge, parallel Old
響應(yīng)時間優(yōu)先:CMS,G1
Serial收集器
單線程收集器,在進行垃圾收集時,必須暫停其他所有的工作線程,直至Serial收集器收集結(jié)束為止(stop the world)。虛擬機運行在Client模式下的默認(rèn)的新生代收集器

ParNew收集器
ParNew收集器就是Serial收集器的多線程版本,它也是一個新生代收集器,目前只有它能和CMS收集器(Concurrent Mark Sweep)配合工作。

Parallel收集器(parallel Scavenge, parallel Old)

CMS收集器
CMS(Concurrent Mark Sweep)收集器是一種以獲取最短回收停頓時間為目標(biāo)的收集器,作用于老年代,采用的是標(biāo)記-清除算法。
CMS收集器工作的整個流程分為以下4個步驟:
- 初始標(biāo)記(CMS initial mark):僅僅只是標(biāo)記一下GC Roots能直接關(guān)聯(lián)到的對象,速度很快,需要“Stop The World”。
- 并發(fā)標(biāo)記(CMS concurrent mark):進行GC Roots Tracing的過程,在整個過程中耗時最長。
- 重新標(biāo)記(CMS remark):為了修正并發(fā)標(biāo)記期間因用戶程序繼續(xù)運作而導(dǎo)致標(biāo)記產(chǎn)生變動的那一部分對象的標(biāo)記記錄,這個階段的停頓時間一般會比初始標(biāo)記階段稍長一些,但遠(yuǎn)比并發(fā)標(biāo)記的時間短。此階段也需要“Stop The World”。
-
并發(fā)清除(CMS concurrent sweep)
cms
優(yōu)點:
- 并發(fā)收集
- 低停頓
缺點: - 因為是和用戶工作線程并發(fā)執(zhí)行的,所以會影響用戶線程的CPU使用。
- 無法處理浮動垃圾
由于CMS并發(fā)清理階段用戶線程還在運行著,伴隨程序運行自然就還會有新的垃圾不斷產(chǎn)生。這一部分垃圾出現(xiàn)在標(biāo)記過程之后,CMS無法再當(dāng)次收集中處理掉它們,只好留待下一次GC時再清理掉。這一部分垃圾就被稱為“浮動垃圾”。也是由于在垃圾收集階段用戶線程還需要運行,那也就還需要預(yù)留有足夠的內(nèi)存空間給用戶線程使用,因此CMS收集器不能像其他收集器那樣等到老年代幾乎完全被填滿了再進行收集,需要預(yù)留一部分空間提供并發(fā)收集時的程序運作使用。
*標(biāo)記-清除算法導(dǎo)致的空間碎片
空間碎片過多時,將會給大對象分配帶來很大麻煩,往往出現(xiàn)老年代空間剩余,但無法找到足夠大連續(xù)空間來分配當(dāng)前對象。這時候CMS會退化為Serial Old。
G1收集器
G1和其他GC算法最大的區(qū)別是弱化分代概念,引入分區(qū)思想

G1 GC切分堆內(nèi)存為多個區(qū)間(Region),從而避免很多GC操作在整個Java堆或者整個年輕代進行。有的分區(qū)內(nèi)垃圾對象特別多,有的分區(qū)內(nèi)垃圾對象很少,G1會優(yōu)先回收垃圾對象特別多的分區(qū),這樣可以花費較少的時間來回收這些分區(qū)的垃圾,這也就是G1名字的由來,即首先收集垃圾最多的分區(qū)。
G1的垃圾收集周期主要有4種類型:年輕代收集周期、多級并發(fā)標(biāo)記周期、混合收集周期和full GC(轉(zhuǎn)移失敗的安全保護機制)
年輕代收集(YGC)
應(yīng)用剛啟動,慢慢流量進來,開始生成對象。G1會選一個分區(qū)并指定他為eden分區(qū),當(dāng)這塊分區(qū)用滿了之后,G1會選一個新的分區(qū)作為eden分區(qū),這個操作會一直進行下去直到達到eden分區(qū)上限,也就是說eden分區(qū)已經(jīng)被占滿,那么會觸發(fā)一次年輕代收集。
年輕代收集首先做的就是遷移存活對象,它使用單eden,雙survivor進行復(fù)制算法,它將存活的對象從eden分區(qū)轉(zhuǎn)移到survivor分區(qū),survivor分區(qū)內(nèi)的某些對象達到了任期閾值之后,會晉升到老年代分區(qū)中。原有的年輕代分區(qū)會被整個回收掉。
