
Serial
Serial是最基本、發(fā)展歷史最悠久的收集器。在JDK 1.3.1之前是JAVA虛擬機(jī)新生代收集的唯一選擇
新生代:Serial,采用復(fù)制算法。
老年代:Serial Old,采用標(biāo)記整理算法
參數(shù):
-XX:+UseSerialGC,新生代、老年代都會(huì)使用串行回收器。
特點(diǎn):
- 在進(jìn)行垃圾收集時(shí),必須
暫停其他所有工作線程; -
單線程。“單線程”并不僅僅說(shuō)明它只會(huì)使用一個(gè)CPU或一個(gè)收集線程去完成垃圾收集工作; - 簡(jiǎn)單而高效(與其他收集器的單線程比),對(duì)于限定單個(gè)CPU的環(huán)境來(lái)說(shuō),沒(méi)有線程交互的開(kāi)銷,專心做GC,自然可以獲得最高的單線程效率。
- Serial收集器對(duì)于運(yùn)行在client模式下的應(yīng)用是一個(gè)很好的選擇(到目前為止,它依然是虛擬機(jī)運(yùn)行在
client模式下的默認(rèn)新生代收集器)
ParNew
ParNew收集器其實(shí)就是Serial收集器的多線程版本。
新生代:ParNew,采用復(fù)制算法
老年代:不可用
參數(shù):
-XX:+UseParNewGC 新生代開(kāi)啟ParNew收集器+老年代串行
-XX:ParallelGCThreads 設(shè)置并行收集線程數(shù)量
特點(diǎn):
- 在進(jìn)行垃圾收集時(shí),必須
暫停其他所有工作線程; -
并行多線程,其余的行為、特點(diǎn)和Serial收集器一樣,兩個(gè)收集器共用了許多代碼; - 指定使用CMS后,會(huì)默認(rèn)使用ParNew作為新生代收集(-XX:+UseConcMarkSweepGC);
- 在
Server模式下,ParNew收集器是一個(gè)非常重要的收集器,因?yàn)槌齋erial外,目前只有它能與CMS收集器配合工作; - 多條GC線程并行垃圾清理,速度比Serial有一定的提升。單個(gè)CPU環(huán)境中,存在線程交互開(kāi)銷,不會(huì)比Serail收集器有更好的效果。
Parallel Scavenge
新生代多線程并行收集器
新生代:Parallel Scavenge,采用復(fù)制算法
老年代:Parallel Old,才用標(biāo)記整理算法
參數(shù):
-XX:+UseParallelGC 使用Parallel收集器+ 老年代串行
-XX:+UseParallelOldGC 新生代和老年代都使用并行收集器
-XX:GCTimeRadio 設(shè)置吞吐量大小
-XX:MaxGCPauseMillis 設(shè)置最大GC停頓時(shí)間
-XX:+UseAdaptiveSizePolicy 開(kāi)啟GC 自適應(yīng)的調(diào)節(jié)策略。
特點(diǎn):
- 在進(jìn)行垃圾收集時(shí),必須
暫停其他所有工作線程; -
并行多線程。 - 追求高
吞吐量。CMS等收集器的關(guān)注點(diǎn)更多的是用戶線程的停頓時(shí)間(提高用戶體驗(yàn)),而Parallel Scavenge關(guān)注的是吞吐量(用戶線程時(shí)間/(用戶線程時(shí)間+GC線程時(shí)間))。 - 在
server模式下,默認(rèn)采用Parallel Scavenge收集器 -
自適應(yīng)的調(diào)節(jié)策略。只要設(shè)置最大堆(-Xmx)和MaxGCPauseMillis或GCTimeRadio,收集器會(huì)自動(dòng)調(diào)整新生代的大小、Eden和Survior的比例、對(duì)象進(jìn)入老年代的年齡,以最大程度上接近我們?cè)O(shè)置的MaxGCPauseMillis或GCTimeRadio
CMS
以最短回收停頓時(shí)間為目標(biāo)的多線程并發(fā)收集器
新生代:不可用
老年代:Concurrent Mark Sweep,采用標(biāo)記清除算法
參數(shù):
-XX:+UseConcMarkSweepGC 開(kāi)啟CMS收集器
-XX:+ UseCMSCompactAtFullCollection 默認(rèn)開(kāi)啟。并發(fā)收集頂不住進(jìn)行Full GC后(CMS并發(fā)GC不是“full GC”),進(jìn)行一次碎片整理。整理過(guò)程是獨(dú)占的,會(huì)引起停頓時(shí)間變長(zhǎng)
-XX:CMSFullGCsBeforeCompaction 在上一次壓縮后,再執(zhí)行多少次不壓縮的full GC后,才會(huì)做壓縮。默認(rèn)是0,也就是在默認(rèn)配置下每次CMS GC頂不住了而要轉(zhuǎn)入full GC的時(shí)候都會(huì)做壓縮
-XX:CMSInitiatingOccupancyFraction 內(nèi)存占用率達(dá)到多少的時(shí)候開(kāi)始CMS收集
-XX:+UseCMSInitiatingOccupancyOnly 設(shè)定回收閾值(CMSInitiatingOccupancyFraction指定),如果不指定,JVM僅在第一次使用設(shè)定值,后續(xù)則自動(dòng)調(diào)整.
-XX:ParallelCMSThreads:并行收集時(shí)的線程數(shù)
步驟:
- 初始標(biāo)記
暫停所有的其他線程,初始標(biāo)記僅僅標(biāo)記GC Roots能直接關(guān)聯(lián)到的對(duì)象,速度很快 - 并發(fā)標(biāo)記
進(jìn)行GC Roots Tracing的過(guò)程 - 重新標(biāo)記
暫停所有的其他線程,修正并發(fā)標(biāo)記期間用戶程序繼續(xù)運(yùn)行產(chǎn)生變動(dòng)的部分對(duì)象的標(biāo)記記錄(采用多線程并行執(zhí)行來(lái)提升效率) - 并發(fā)清除
開(kāi)啟用戶線程,同時(shí)GC線程開(kāi)始對(duì)為標(biāo)記的區(qū)域做清掃,回收所有的垃圾對(duì)象
特點(diǎn):
- 初始標(biāo)記、重新標(biāo)記兩個(gè)階段必須
暫停其他所有工作線程; -
并發(fā)多線程。 - 追求高
響應(yīng)速度。希望系統(tǒng)停頓時(shí)間最短,以給用戶帶來(lái)較好的體驗(yàn)
缺點(diǎn):
-
CPU資源敏感?;厥站€程占用一定線程資源,吞吐量下降,默認(rèn)回收線程數(shù)是(CPU數(shù)+3)/4。 - 無(wú)法處理
浮動(dòng)垃圾。在并發(fā)清除時(shí),用戶線程新產(chǎn)生的垃圾,稱為浮動(dòng)垃圾。可能出現(xiàn)“Concurrent Mode Failure”而導(dǎo)致另一次Full GC。因此CMS不能像其他收集器那樣等到老年代幾乎填滿再進(jìn)行收集,需要預(yù)留一部分空間提供并發(fā)收集期間程序運(yùn)行使用。JDK1.5時(shí),空間使用68%后CMS會(huì)被激活(JDK1.6后為92%)。如果收集期間內(nèi)存不足,則會(huì)出現(xiàn)“Concurrent Mode Failure”失敗,臨時(shí)啟用Serial Old收集器。 -
空間碎片。CMS是基于“標(biāo)記+清除”算法來(lái)回收老年代對(duì)象的,因此長(zhǎng)時(shí)間運(yùn)行后會(huì)產(chǎn)生大量的空間碎片問(wèn)題。
內(nèi)存模型

Young : Old = 1:2
Eden區(qū):Survivor區(qū) = 8:1
收集過(guò)程:
- 對(duì)象首先在Eden中分配
- 如果Eden區(qū)空間不足了,進(jìn)行一次Minor GC,把Eden區(qū)的存活對(duì)象轉(zhuǎn)移到其中一個(gè)Survivor區(qū)(稱為From區(qū)),非存活對(duì)象進(jìn)行清理,然后在Eden區(qū)給新創(chuàng)建的對(duì)象分配空間
- 隨著對(duì)象的增多,Eden區(qū)空間又不足了,進(jìn)行一次Minor GC,把Eden區(qū)和From區(qū)的存活對(duì)象轉(zhuǎn)移到另一個(gè)Survivor區(qū)(稱為To區(qū)),非存活對(duì)象進(jìn)行清理,然后From變成To,To變成From,然后在Eden區(qū)給新創(chuàng)建的對(duì)象分配空間
- 進(jìn)入老年代
4.1 To區(qū)空間不足,將存活對(duì)象移入老年代
4.2 大對(duì)象直接進(jìn)入老年代(PretenureSizeThreshold指定,默認(rèn)3M)
4.3 長(zhǎng)期存活對(duì)象移入老年代,每經(jīng)過(guò)一次Minor GC年齡加1。年齡增加到一定程度(MaxTenuringThreshold指定,默認(rèn)15)移入老年代
4.4 From空間中,相同年齡所有對(duì)象的大小總和大于From空間總和的一半 - 如果進(jìn)入老年代時(shí),老年代空間不足進(jìn)行Full GC。
參數(shù):
-XX:PretenureSizeThreshold 大于這個(gè)值得對(duì)象直接進(jìn)入老年代,避免新生代發(fā)生大量復(fù)制
-XX:MaxTenuringThreshold 晉升老年代的年齡
-XX:MetaspaceSize Metaspace擴(kuò)容時(shí)觸發(fā)FullGC的初始化閾值
-Xms 初始分配的堆內(nèi)存,默認(rèn)是物理內(nèi)存的1/64
-Xmx最大分配的堆內(nèi)存,默認(rèn)是物理內(nèi)存的1/4