HotSpot JVM收集器
上面有7中收集器,分為兩塊双抽,上面為新生代收集器百框,下面是老年代收集器。如果兩個(gè)收集器之間存在連線牍汹,就說(shuō)明它們可以搭配使用铐维。
Serial(串行GC)收集器
Serial收集器是一個(gè)新生代收集器,單線程執(zhí)行慎菲,使用復(fù)制算法嫁蛇。它在進(jìn)行垃圾收集時(shí),必須暫停其他所有的工作線程(用戶線程)露该。是Jvm client模式下默認(rèn)的新生代收集器睬棚。對(duì)于限定單個(gè)CPU的環(huán)境來(lái)說(shuō),Serial收集器由于沒(méi)有線程交互的開銷解幼,專心做垃圾收集自然可以獲得最高的單線程收集效率抑党。
ParNew(并行GC)收集器
ParNew收集器其實(shí)就是serial收集器的多線程版本,除了使用多條線程進(jìn)行垃圾收集之外撵摆,其余行為與Serial收集器一樣底靠。
Parallel Scavenge(并行回收GC)收集器
Parallel Scavenge收集器也是一個(gè)新生代收集器,它也是使用復(fù)制算法的收集器特铝,又是并行多線程收集器暑中。parallel Scavenge收集器的特點(diǎn)是它的關(guān)注點(diǎn)與其他收集器不同,CMS等收集器的關(guān)注點(diǎn)是盡可能地縮短垃圾收集時(shí)用戶線程的停頓時(shí)間苟呐,而parallel Scavenge收集器的目標(biāo)則是達(dá)到一個(gè)可控制的吞吐量痒芝。吞吐量= 程序運(yùn)行時(shí)間/(程序運(yùn)行時(shí)間 + 垃圾收集時(shí)間)俐筋,虛擬機(jī)總共運(yùn)行了100分鐘牵素。其中垃圾收集花掉1分鐘,那吞吐量就是99%澄者。
Serial Old(串行GC)收集器
Serial Old是Serial收集器的老年代版本笆呆,它同樣使用一個(gè)單線程執(zhí)行收集,使用“標(biāo)記-整理”算法粱挡。主要使用在Client模式下的虛擬機(jī)赠幕。
Parallel Old(并行GC)收集器
Parallel Old是Parallel Scavenge收集器的老年代版本,使用多線程和“標(biāo)記-整理”算法询筏。
CMS(并發(fā)GC)收集器
CMS(Concurrent Mark Sweep)收集器是一種以獲取最短回收停頓時(shí)間為目標(biāo)的收集器榕堰。
CMS收集器是基于“標(biāo)記-清除”算法實(shí)現(xiàn)的,整個(gè)收集過(guò)程大致分為4個(gè)步驟:
①.初始標(biāo)記(CMS initial mark)
②.并發(fā)標(biāo)記(CMS concurrenr mark)
③.重新標(biāo)記(CMS remark)
④.并發(fā)清除(CMS concurrent sweep)
其中初始標(biāo)記、重新標(biāo)記這兩個(gè)步驟任然需要停頓其他用戶線程逆屡。初始標(biāo)記僅僅只是標(biāo)記出GC ROOTS能直接關(guān)聯(lián)到的對(duì)象圾旨,速度很快,并發(fā)標(biāo)記階段是進(jìn)行GC ROOTS 根搜索算法階段魏蔗,會(huì)判定對(duì)象是否存活砍的。而重新標(biāo)記階段則是為了修正并發(fā)標(biāo)記期間,因用戶程序繼續(xù)運(yùn)行而導(dǎo)致標(biāo)記產(chǎn)生變動(dòng)的那一部分對(duì)象的標(biāo)記記錄莺治,這個(gè)階段的停頓時(shí)間會(huì)被初始標(biāo)記階段稍長(zhǎng)廓鞠,但比并發(fā)標(biāo)記階段要短。
由于整個(gè)過(guò)程中耗時(shí)最長(zhǎng)的并發(fā)標(biāo)記和并發(fā)清除過(guò)程中谣旁,收集器線程都可以與用戶線程一起工作床佳,所以整體來(lái)說(shuō),CMS收集器的內(nèi)存回收過(guò)程是與用戶線程一起并發(fā)執(zhí)行的榄审。
CMS收集器的優(yōu)點(diǎn):并發(fā)收集夕土、低停頓,但是CMS還遠(yuǎn)遠(yuǎn)達(dá)不到完美瘟判,主要有三個(gè)顯著缺點(diǎn):
1怨绣,CMS收集器對(duì)CPU資源非常敏感。在并發(fā)階段拷获,雖然不會(huì)導(dǎo)致用戶線程停頓篮撑,但是會(huì)占用CPU資源而導(dǎo)致引用程序變慢,總吞吐量下降匆瓜。CMS默認(rèn)啟動(dòng)的回收線程數(shù)是:(CPU數(shù)量+3) / 4赢笨。
2,CMS收集器無(wú)法處理浮動(dòng)垃圾驮吱,可能出現(xiàn)“Concurrent Mode Failure“茧妒,失敗后而導(dǎo)致另一次Full GC的產(chǎn)生。由于CMS并發(fā)清理階段用戶線程還在運(yùn)行左冬,伴隨程序的運(yùn)行自熱會(huì)有新的垃圾不斷產(chǎn)生桐筏,這一部分垃圾出現(xiàn)在標(biāo)記過(guò)程之后,CMS無(wú)法在本次收集中處理它們拇砰,只好留待下一次GC時(shí)將其清理掉梅忌。這一部分垃圾稱為“浮動(dòng)垃圾”。也是由于在垃圾收集階段用戶線程還需要運(yùn)行除破,,即需要預(yù)留足夠的內(nèi)存空間給用戶線程使用牧氮,因此CMS收集器不能像其他收集器那樣等到老年代幾乎完全被填滿了再進(jìn)行收集,需要預(yù)留一部分內(nèi)存空間提供并發(fā)收集時(shí)的程序運(yùn)作使用瑰枫。
在默認(rèn)設(shè)置下踱葛,CMS收集器在老年代使用了68%的空間時(shí)就會(huì)被激活,也可以通過(guò)參數(shù)-XX:CMSInitiatingOccupancyFraction的值來(lái)提供觸發(fā)百分比,以降低內(nèi)存回收次數(shù)提高性能尸诽。要是CMS運(yùn)行期間預(yù)留的內(nèi)存無(wú)法滿足程序其他線程需要圾笨,就會(huì)出現(xiàn)“Concurrent Mode Failure”失敗,這時(shí)候虛擬機(jī)將啟動(dòng)后備預(yù)案:臨時(shí)啟用Serial Old收集器來(lái)重新進(jìn)行老年代的垃圾收集逊谋,這樣停頓時(shí)間就很長(zhǎng)了擂达。
所以說(shuō)參數(shù)-XX:CMSInitiatingOccupancyFraction設(shè)置的過(guò)高將會(huì)很容易導(dǎo)致“Concurrent Mode Failure”失敗,性能反而降低胶滋。
3板鬓,最后一個(gè)缺點(diǎn),CMS是基于“標(biāo)記-清除”算法實(shí)現(xiàn)的收集器究恤,使用“標(biāo)記-清除”算法收集后俭令,會(huì)產(chǎn)生大量碎片〔克蓿空間碎片太多時(shí)抄腔,將會(huì)給對(duì)象分配帶來(lái)很多麻煩,比如說(shuō)大對(duì)象理张,內(nèi)存空間找不到連續(xù)的空間來(lái)分配不得不提前觸發(fā)一次Full GC赫蛇。為了解決這個(gè)問(wèn)題,CMS收集器提供了一個(gè)-XX:UseCMSCompactAtFullCollection開關(guān)參數(shù)雾叭,用于在Full GC之后增加一個(gè)碎片整理過(guò)程悟耘,還可通過(guò)-XX:CMSFullGCBeforeCompaction參數(shù)設(shè)置執(zhí)行多少次不壓縮的Full GC之后,跟著來(lái)一次碎片整理過(guò)程织狐。
G1收集器
G1(Garbage First)收集器是JDK1.7提供的一個(gè)新收集器暂幼,G1收集器基于“標(biāo)記-整理”算法實(shí)現(xiàn),也就是說(shuō)不會(huì)產(chǎn)生內(nèi)存碎片移迫。還有一個(gè)特點(diǎn)之前的收集器進(jìn)行收集的范圍都是整個(gè)新生代或老年代旺嬉,而G1將整個(gè)Java堆(包括新生代,老年代)厨埋。
垃圾收集器參數(shù)總結(jié):
-XX:+ 啟用選項(xiàng) -XX:- 不啟用選項(xiàng) -XX:= -XX:=
參數(shù) 描述 -XX:+UseSerialGC Jvm運(yùn)行在Client模式下的默認(rèn)值邪媳,打開此開關(guān)后,使用Serial + Serial Old的收集器組合進(jìn)行內(nèi)存回收 -XX:+UseParNewGC 打開此開關(guān)后揽咕,使用ParNew + Serial Old的收集器進(jìn)行垃圾回收 -XX:+UseConcMarkSweepGC 使用ParNew + CMS + Serial Old的收集器組合進(jìn)行內(nèi)存回收悲酷,Serial Old作為CMS出現(xiàn)“Concurrent Mode Failure”失敗后的后備收集器使用套菜。 -XX:+UseParallelGC Jvm運(yùn)行在Server模式下的默認(rèn)值亲善,打開此開關(guān)后,使用Parallel Scavenge + Serial Old的收集器組合進(jìn)行回收 -XX:+UseParallelOldGC 使用Parallel Scavenge + Parallel Old的收集器組合進(jìn)行回收 -XX:SurvivorRatio 新生代中Eden區(qū)域與Survivor區(qū)域的容量比值逗柴,默認(rèn)為8蛹头,代表Eden:Subrvivor = 8:1 -XX:PretenureSizeThreshold 直接晉升到老年代對(duì)象的大小,設(shè)置這個(gè)參數(shù)后,大于這個(gè)參數(shù)的對(duì)象將直接在老年代分配 -XX:MaxTenuringThreshold 晉升到老年代的對(duì)象年齡渣蜗,每次Minor GC之后屠尊,年齡就加1,當(dāng)超過(guò)這個(gè)參數(shù)的值時(shí)進(jìn)入老年代 -XX:UseAdaptiveSizePolicy 動(dòng)態(tài)調(diào)整java堆中各個(gè)區(qū)域的大小以及進(jìn)入老年代的年齡 -XX:+HandlePromotionFailure 是否允許新生代收集擔(dān)保耕拷,進(jìn)行一次minor gc后, 另一塊Survivor空間不足時(shí)讼昆,將直接會(huì)在老年代中保留 -XX:ParallelGCThreads 設(shè)置并行GC進(jìn)行內(nèi)存回收的線程數(shù) -XX:GCTimeRatio GC時(shí)間占總時(shí)間的比列,默認(rèn)值為99骚烧,即允許1%的GC時(shí)間浸赫,僅在使用Parallel Scavenge 收集器時(shí)有效 -XX:MaxGCPauseMillis 設(shè)置GC的最大停頓時(shí)間,在Parallel Scavenge 收集器下有效 -XX:CMSInitiatingOccupancyFraction 設(shè)置CMS收集器在老年代空間被使用多少后出發(fā)垃圾收集赃绊,默認(rèn)值為68%既峡,僅在CMS收集器時(shí)有效,-XX:CMSInitiatingOccupancyFraction=70 -XX:+UseCMSCompactAtFullCollection 由于CMS收集器會(huì)產(chǎn)生碎片碧查,此參數(shù)設(shè)置在垃圾收集器后是否需要一次內(nèi)存碎片整理過(guò)程运敢,僅在CMS收集器時(shí)有效 -XX:+CMSFullGCBeforeCompaction 設(shè)置CMS收集器在進(jìn)行若干次垃圾收集后再進(jìn)行一次內(nèi)存碎片整理過(guò)程,通常與UseCMSCompactAtFullCollection參數(shù)一起使用 -XX:+UseFastAccessorMethods 原始類型優(yōu)化 -XX:+DisableExplicitGC 是否關(guān)閉手動(dòng)System.gc -XX:+CMSParallelRemarkEnabled 降低標(biāo)記停頓 -XX:LargePageSizeInBytes 內(nèi)存頁(yè)的大小不可設(shè)置過(guò)大忠售,會(huì)影響Perm的大小传惠,-XX:LargePageSizeInBytes=128m
Client、Server模式默認(rèn)GC
新生代GC方式 老年代和持久代GC方式
新生代GC方式 老年代和持久代GC方式