|
【聲明】 歡迎轉(zhuǎn)載,但請保留文章原始出處→_→ 生命壹號:http://www.cnblogs.com/smyhvae/ 文章來源:http://www.cnblogs.com/smyhvae/p/4748313.html
本文主要內(nèi)容:
零、堆的回顧: 新生代中的98%對象都是“朝生夕死”的,所以并不需要按照1:1的比例來劃分內(nèi)存空間,而是將內(nèi)存分為一塊比較大的Eden空間和兩塊較小的Survivor空間,每次使用Eden和其中一塊Survivor。當(dāng)回收時,將Eden和Survivor中還存活著的對象一次性地復(fù)制到另外一塊Survivor空間上,最后清理掉Eden和剛才用過的Survivor空間。HotSpot虛擬機(jī)默認(rèn)Eden和Survivor的大小比例是8:1,也就是說,每次新生代中可用內(nèi)存空間為整個新生代容量的90%(80%+10%),只有10%的空間會被浪費(fèi)。 當(dāng)然,98%的對象可回收只是一般場景下的數(shù)據(jù),我們沒有辦法保證每次回收都只有不多于10%的對象存活,當(dāng)Survivor空間不夠用時,需要依賴于老年代進(jìn)行分配擔(dān)保,所以大對象直接進(jìn)入老年代。 堆的結(jié)構(gòu)如下圖所示: 垃圾收集器: 如果說收集算法時內(nèi)存回收的方法論,那么垃圾收集器就是內(nèi)存回收的具體實(shí)現(xiàn)。 雖然我們在對各種收集器進(jìn)行比較,但并非為了挑出一個最好的收集器。因?yàn)橹钡浆F(xiàn)在位置還沒有最好的收集器出現(xiàn),更加沒有萬能的收集器,所以我們選擇的只是對具體應(yīng)用最合適的收集器。
一、串行收集器:Serial收集器
新生代、老年代都會使用串行回收 新生代復(fù)制算法 老年代標(biāo)記-整理 總結(jié):Serial收集器對于運(yùn)行在Client模式下的虛擬機(jī)來說是一個很好的選擇。 這個收集器是一個單線程的收集器,但它的單線程的意義并不僅僅說明它只會使用一個CPU或一條收集線程去完成垃圾收集工作,更重要的是在它進(jìn)行垃圾收集時,必須暫停其他所有的工作線程,直到它收集結(jié)束。收集器的運(yùn)行過程如下圖所示:
二、并行收集器: 1、ParNew收集器:
新生代并行 老年代串行
2、Parallel Scanvenge收集器:
3、Parallel Old收集器:
如下圖所示: 各種參數(shù)設(shè)置:
最大停頓時間,單位毫秒 GC盡力保證回收時間不超過設(shè)定值
0-100的取值范圍 垃圾收集時間占總時間的比 默認(rèn)99,即最大允許1%時間做GC 注:這兩個參數(shù)是矛盾的。因?yàn)?span style="color: #0000ff;">停頓時間和吞吐量不可能同時調(diào)優(yōu)。我們一方買希望停頓時間少,另外一方面希望吞吐量高,其實(shí)這是矛盾的。因?yàn)椋涸贕C的時候,垃圾回收的工作總量是不變的,如果將停頓時間減少,那頻率就會提高;既然頻率提高了,說明就會頻繁的進(jìn)行GC,那吞吐量就會減少,性能就會降低。 吞吐量:CPU用于用戶代碼的時間/CPU總消耗時間的比值,即=運(yùn)行用戶代碼的時間/(運(yùn)行用戶代碼時間+垃圾收集時間)。比如,虛擬機(jī)總共運(yùn)行了100分鐘,其中垃圾收集花掉1分鐘,那吞吐量就是99%。 注2:以上所有的收集器當(dāng)中,當(dāng)執(zhí)行GC時,都會stop the world,但是下面的CMS收集器卻不會這樣。
三、CMS收集器: CMS收集器(Concurrent Mark Sweep:并發(fā)標(biāo)記清除)是一種以獲取最短回收停頓時間為目標(biāo)的收集器。適合應(yīng)用在互聯(lián)網(wǎng)站或者B/S系統(tǒng)的服務(wù)器上,這類應(yīng)用尤其重視服務(wù)器的響應(yīng)速度,希望系統(tǒng)停頓時間最短。
注:這里的并發(fā)指的是與用戶線程一起執(zhí)行。
2、CMS收集器運(yùn)行過程:(著重實(shí)現(xiàn)了標(biāo)記的過程) (1)初始標(biāo)記 根可以直接關(guān)聯(lián)到的對象 速度快 (2)并發(fā)標(biāo)記(和用戶線程一起) 主要標(biāo)記過程,標(biāo)記全部對象 (3)重新標(biāo)記 由于并發(fā)標(biāo)記時,用戶線程依然運(yùn)行,因此在正式清理前,再做修正 (4)并發(fā)清除(和用戶線程一起) 基于標(biāo)記結(jié)果,直接清理對象 整個過程如下圖所示: 其中,初始標(biāo)記和重新標(biāo)記時,需要stop the world。 整個過程中耗時最長的是并發(fā)標(biāo)記和并發(fā)清除,這兩個過程都可以和用戶線程一起工作。 打印GC日志舉例如下: 3、CMS收集器特點(diǎn): (1)盡可能降低停頓 (2)會影響系統(tǒng)整體吞吐量和性能 比如,在用戶線程運(yùn)行過程中,分一半CPU去做GC,系統(tǒng)性能在GC階段,反應(yīng)速度就下降一半 (3)清理不徹底 因?yàn)樵谇謇黼A段,用戶線程還在運(yùn)行,會產(chǎn)生新的垃圾,無法清理 (4)因?yàn)楹陀脩艟€程一起運(yùn)行,不能在空間快滿時再清理 -XX:CMSInitiatingOccupancyFraction設(shè)置觸發(fā)GC的閾值 如果不幸內(nèi)存預(yù)留空間不夠,就會引起concurrent mode failure 我們來看一下concurrent mode failure的日志: 碰到上圖中的情況,我們需要使用串行收集器作為后備。
4、既然標(biāo)記清除算法會造成內(nèi)存空間的碎片化,CMS收集器為什么使用標(biāo)記清除算法而不是使用標(biāo)記整理算法: 答案: CMS收集器更加關(guān)注停頓,它在做GC的時候是和用戶線程一起工作的(并發(fā)執(zhí)行),如果使用標(biāo)記整理算法的話,那么在清理的時候就會去移動可用對象的內(nèi)存空間,那么應(yīng)用程序的線程就很有可能找不到應(yīng)用對象在哪里。 為了解決碎片的問題,CMS收集器會有一些整理上的參數(shù),接下來就來講這個。
5、整理時的各種參數(shù):
Full GC后,進(jìn)行一次整理。整理過程是獨(dú)占的,會引起停頓時間變長
設(shè)置進(jìn)行幾次Full GC后,進(jìn)行一次碎片整理
設(shè)定CMS的線程數(shù)量
四、GC參數(shù)的整理: -XX:+UseSerialGC:在新生代和老年代使用串行收集器 -XX:SurvivorRatio:設(shè)置eden區(qū)大小和survivior區(qū)大小的比例 -XX:NewRatio:新生代和老年代的比 -XX:+UseParNewGC:在新生代使用并行收集器 -XX:+UseParallelGC :新生代使用并行回收收集器 -XX:+UseParallelOldGC:老年代使用并行回收收集器 -XX:ParallelGCThreads:設(shè)置用于垃圾回收的線程數(shù) -XX:+UseConcMarkSweepGC:新生代使用并行收集器,老年代使用CMS+串行收集器 -XX:ParallelCMSThreads:設(shè)定CMS的線程數(shù)量 -XX:CMSInitiatingOccupancyFraction:設(shè)置CMS收集器在老年代空間被使用多少后觸發(fā) -XX:+UseCMSCompactAtFullCollection:設(shè)置CMS收集器在完成垃圾收集后是否要進(jìn)行一次內(nèi)存碎片的整理 -XX:CMSFullGCsBeforeCompaction:設(shè)定進(jìn)行多少次CMS垃圾回收后,進(jìn)行一次內(nèi)存壓縮 -XX:+CMSClassUnloadingEnabled:允許對類元數(shù)據(jù)進(jìn)行回收 -XX:CMSInitiatingPermOccupancyFraction:當(dāng)永久區(qū)占用率達(dá)到這一百分比時,啟動CMS回收 -XX:UseCMSInitiatingOccupancyOnly:表示只在到達(dá)閥值的時候,才進(jìn)行CMS回收
最后的總結(jié): 為了減輕GC壓力,我們需要注意些什么?
參考鏈接: http://www.cnblogs.com/zuoxiaolong/p/jvm8.html
|
|
|
來自: primivite_ > 《jvm》