溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

面試官常問的垃圾回收器有哪些

發(fā)布時(shí)間:2021-10-19 13:44:44 來源:億速云 閱讀:110 作者:iii 欄目:web開發(fā)

這篇文章主要介紹“面試官常問的垃圾回收器有哪些”,在日常操作中,相信很多人在面試官常問的垃圾回收器有哪些問題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”面試官常問的垃圾回收器有哪些”的疑惑有所幫助!接下來,請(qǐng)跟著小編一起來學(xué)習(xí)吧!

JVM堆內(nèi)存概覽

在聊垃圾回收器之前,我們先來看看JVM堆內(nèi)存的區(qū)域劃分是怎么樣的,看下圖

面試官常問的垃圾回收器有哪些

  •  因?yàn)樘摂M機(jī)使用的垃圾回收算法是分代收集算法,所以堆內(nèi)存被分為了新生代和老年代

  •  新生代使用的垃圾回收算法是復(fù)制算法,所以新生代又被分為了 Eden 和Survivor;空間大小比例默認(rèn)為8:2

  •  Survivor又被分為了S0、S1,這兩個(gè)的空間大小比例為1:1

內(nèi)存分配以及垃圾回收

  1.  對(duì)象優(yōu)先在Eden區(qū)進(jìn)行分配,如果Eden區(qū)滿了之后會(huì)觸發(fā)一次Minor GC

  2.  Minor GC之后從Eden存活下來的對(duì)象將會(huì)被移動(dòng)到S0區(qū)域,當(dāng)S0內(nèi)存滿了之后又會(huì)被觸發(fā)一次Minor GC,S0區(qū)存活下來的對(duì)象會(huì)被移動(dòng)到S1區(qū),S0區(qū)空閑;S1滿了之后在Minor GC,存活下來的再次移動(dòng)到S0區(qū),S1區(qū)空閑,這樣反反復(fù)復(fù)GC,每GC一次,對(duì)象的年齡就漲一歲,默認(rèn)達(dá)到15歲之后就會(huì)進(jìn)入老年代,對(duì)于晉身到老年代的年齡閾值可以通過參數(shù) -XX:MaxTenuringThreshold設(shè)置

  3.  在Minor GC之后需要的發(fā)送晉身到老年代的對(duì)象沒有空間安置,那么就會(huì)觸發(fā)Full GC (這步非絕對(duì),視垃圾回收器決定)

Minor GC和Full GC的區(qū)別:Minor GC是指發(fā)生在新生代的垃圾收集行為,由于對(duì)象優(yōu)先在Eden區(qū)分配,并且很多對(duì)象都是朝生夕死,所以觸發(fā)的頻率相對(duì)較高;由于采用的復(fù)制算法,所以一般回收速度非??臁ull GC是指發(fā)生在老年代的垃圾收集行為,F(xiàn)ull GC的速度一般會(huì)比Minor GC慢10倍以上;所以不能讓JVM頻繁的發(fā)生Full GC

為了能夠更好的適應(yīng)不同程序的內(nèi)存情況,JVM也不一定要求必須達(dá)到年齡15歲才能晉身到老年代,如果在Survivor區(qū)中相同年齡的所有對(duì)象大小總和大于Survivor區(qū)空間的一半,年齡大于或者等于這個(gè)年齡的對(duì)象將會(huì)直接進(jìn)入到老年代

Full GC觸發(fā)條件

  •  代碼中調(diào)用System.gc()

  •  老年代空間不足/滿了

  •  持久區(qū)空間不足/滿了

注意:大對(duì)象會(huì)直接在老年代分配內(nèi)存,可以通過參數(shù)-XX:PretenureSizeThreshold控制對(duì)象的大小,通常遇到的大對(duì)象是很長的字符串或者數(shù)組,如果分配了一大群大對(duì)象只是臨時(shí)使用,生命很短暫,那么就會(huì)頻繁的發(fā)生Full GC,但是此時(shí)的新生代的空間還有空閑;寫代碼的時(shí)候,這種情況應(yīng)該避免,特別是在創(chuàng)建數(shù)組的時(shí)候要當(dāng)心

空間擔(dān)保

在新生代發(fā)生Minor GC的時(shí)候,JVM會(huì)先檢查老年代中可分配的連續(xù)空間是否大于新生代所有對(duì)象的總和,如果大于,那么本次Minor GC就可以安全的執(zhí)行;如果不大于,那么JVM會(huì)先去檢查參數(shù)HandlePromotionFailure設(shè)置值是否允許空間擔(dān)保失敗,如果允許,JVM會(huì)繼續(xù)檢查老年代可分配的連續(xù)空間是否大于歷次晉升到老年代對(duì)象的平均大小,如果大于,盡管這次Minor GC是有風(fēng)險(xiǎn)的,JVM也會(huì)嘗試一次Minor GC;如果不允許擔(dān)保失敗,那么JVM直接進(jìn)行Full GC

雖然擔(dān)保有可能會(huì)失敗,導(dǎo)致饒一圈才能進(jìn)行GC,但是還是建議把這個(gè)參數(shù)打開,可以避免JVM頻繁的Full GC

垃圾回收器概覽

面試官常問的垃圾回收器有哪些

從上圖可以看出:

  •  新生代可以使用的垃圾回收器:Serial、ParNew、Parallel Scavenge

  •  老年代可以適用的垃圾回收器:CMS、Serial Old、Parallel Old

  •  G1回收器適用于新生代和老年代

  •  相互之間有連線的表示可以配合使用

  CMS和Serial Old同為老年代回收器,為何相互會(huì)有連線呢?

面試官常問的垃圾回收器有哪些

Serial收集器

這是個(gè)單線程收集器,發(fā)展歷史最悠久的收集器,當(dāng)它在進(jìn)行垃圾收集工作的時(shí)候,其他線程都必須暫停直到垃圾收集結(jié)束(Stop The World)。

雖然Serial收集器存在Stop The World的問題,但是在并行能力較弱的單CPU環(huán)境下往往表現(xiàn)優(yōu)于其他收集器;因?yàn)樗?jiǎn)單而高效,沒有多余的線程交互開銷;Serial對(duì)于運(yùn)行在Client模式下的虛擬機(jī)來說是個(gè)很好的選擇

使用-XX:+UseSerialGC參數(shù)可以設(shè)置新生代使用這個(gè)Serial收集器

ParNew收集器

ParNew收集器是Serial收集器的多線程版本;除了使用了多線程進(jìn)行垃圾收集以外,其他的都和Serial一致;它默認(rèn)開始的線程數(shù)與CPU的核數(shù)相同,可以通過參數(shù)-XX:ParallelGCThreads來設(shè)置線程數(shù)。

從上面的圖可以看出,能夠與CMS配合使用的收集器,除了Serial以外,就只剩下ParNew,所以ParNew通常是運(yùn)行在Server模式下的首選新生代垃圾收集器

使用-XX:+UseParNewGC參數(shù)可以設(shè)置新生代使用這個(gè)并行回收器

Parallel Scavenge收集器

Parallel Scavenge收集器依然是個(gè)采用復(fù)制算法的多線程新生代收集器,它與其他的收集器的不同之處在于它主要關(guān)心的是吞吐量,而其他的收集器關(guān)注的是盡可能的減少用戶線程的等待時(shí)間(縮短Stop The World的時(shí)間)。吞吐量=用戶線程執(zhí)行時(shí)間/(用戶線程執(zhí)行時(shí)間+垃圾收集時(shí)間),虛擬機(jī)總共運(yùn)行100分鐘,其中垃圾收集花費(fèi)時(shí)間1分鐘,那么吞吐量就是 99%

停頓時(shí)間越短適合需要和用戶進(jìn)行交互的程序,良好的響應(yīng)能夠提升用戶的體驗(yàn)。而高效的吞吐量可以充分的利用CPU時(shí)間,盡快的完成計(jì)算任務(wù),所以Parallel Scavenge收集器適用于后臺(tái)計(jì)算型任務(wù)程序。

-XX:MaxGCPauseMillis可以控制垃圾收集的最大暫停時(shí)間,需要注意不要以為把這個(gè)時(shí)間設(shè)置的很小就可以減少垃圾收集暫用的時(shí)間,這可能會(huì)導(dǎo)致發(fā)生頻繁的GC,反而降低了吞吐量

-XX:GCTimeRatio設(shè)置吞吐量大小,參數(shù)是取值范圍0-100的整數(shù),也就是垃圾收集占用的時(shí)間,默認(rèn)是99,那么垃圾收集占用的最大時(shí)間 1%

-XX:+UseAdaptiveSizePolicy 如果打開這個(gè)參數(shù),就不需要用戶手動(dòng)的控制新生代大小,晉升老年代年齡等參數(shù),JVM會(huì)開啟GC自適應(yīng)調(diào)節(jié)策略

Serial Old收集器

Serial Old收集器也是個(gè)單線程收集器,適用于老年代,使用的是標(biāo)記-整理算法,可以配合Serial收集器在Client模式下使用。

它可以作為CMS收集器的后備預(yù)案,如果CMS出現(xiàn)Concurrent Mode Failure,則SerialOld將作為后備收集器。(后面CMS詳細(xì)說明)

Parallel Old收集器

Parallel Old收集器可以配合Parallel Scavenge收集器一起使用達(dá)到“吞吐量?jī)?yōu)先”,它主要是針對(duì)老年代的收集器,使用的是標(biāo)記-整理算法。在注重吞吐量的任務(wù)中可以優(yōu)先考慮使用這個(gè)組合

-XX:+UseParallelOldGc設(shè)置老年代使用該回收器。

XX:+ParallelGCThreads設(shè)置垃圾收集時(shí)的線程數(shù)量。

CMS收集器

CMS收集器是一種以獲取最短回收停頓時(shí)間為目標(biāo)的收集器,在互聯(lián)網(wǎng)網(wǎng)站、B/S架構(gòu)的中常用的收集器就是CMS,因?yàn)橄到y(tǒng)停頓的時(shí)間最短,給用戶帶來較好的體驗(yàn)。

-XX:+UseConcMarkSweepGC設(shè)置老年代使用該回收器。

-XX:ConcGCThreads設(shè)置并發(fā)線程數(shù)量。

CMS采用的是標(biāo)記-清除算法,主要分為了4個(gè)步驟:

  •  初始化標(biāo)記

  •  并發(fā)標(biāo)記

  •  重新標(biāo)記

  •  并發(fā)清除

初始化標(biāo)記和重新標(biāo)記這兩個(gè)步驟依然會(huì)發(fā)生Stop The World,初始化標(biāo)記只是標(biāo)記GC Root能夠直接關(guān)聯(lián)到的對(duì)象,速度較快,并發(fā)標(biāo)記能夠和用戶線程并發(fā)執(zhí)行;重新標(biāo)記是為了修正在并發(fā)標(biāo)記的過程中用戶線程產(chǎn)生的垃圾,這個(gè)時(shí)間比初始化標(biāo)記稍長,比并發(fā)標(biāo)記短很多。整個(gè)過程請(qǐng)看下圖

面試官常問的垃圾回收器有哪些

優(yōu)點(diǎn)

  •  CMS是一款優(yōu)秀的收集器,它的主要優(yōu)點(diǎn):并發(fā)收集、低停頓,因此CMS收集器也被稱為并發(fā)低停頓收集器(Concurrent Low Pause Collector)。

缺點(diǎn)

  •  CMS收集器對(duì)CPU資源非常敏感。 在并發(fā)階段,它雖然不會(huì)導(dǎo)致用戶線程停頓,但會(huì)因?yàn)檎加昧艘徊糠志€程(或者說CPU資源)而導(dǎo)致應(yīng)用程序變慢,總吞吐量會(huì)降低。CMS默認(rèn)啟動(dòng)的回收線程數(shù)是(CPU數(shù)量+3)/4,也就是當(dāng)CPU在4個(gè)以上時(shí),并發(fā)回收時(shí)垃圾收集線程不少于25%的CPU資源,并且隨著CPU數(shù)量的增加而下降。但是當(dāng)CPU不足4個(gè)時(shí)(比如2個(gè)),CMS對(duì)用戶程序的影響就可能變得很大,如果本來CPU負(fù)載就比較大,還要分出一半的運(yùn)算能力去執(zhí)行收集器線程,就可能導(dǎo)致用戶程序的執(zhí)行速度忽然降低了50%,其實(shí)也讓人無法接受。

  •  無法處理浮動(dòng)垃圾。 由于CMS并發(fā)清理階段用戶線程還在運(yùn)行著,伴隨程序運(yùn)行自然就還會(huì)有新的垃圾不斷產(chǎn)生。這一部分垃圾出現(xiàn)在標(biāo)記過程之后,CMS無法再當(dāng)次收集中處理掉它們,只好留待下一次GC時(shí)再清理掉。這一部分垃圾就被稱為“浮動(dòng)垃圾”。也是由于在垃圾收集階段用戶線程還需要運(yùn)行,那也就還需要預(yù)留有足夠的內(nèi)存空間給用戶線程使用,因此CMS收集器不能像其他收集器那樣等到老年代幾乎完全被填滿了再進(jìn)行收集,回收閥值可以通過參數(shù)-XX:CMSInitiatingoccupancyFraction來設(shè)置;如果回收閥值設(shè)置的太大,在CMS運(yùn)行期間如果分配大的對(duì)象找不到足夠的空間就會(huì)出現(xiàn)“Concurrent Mode Failure”失敗,這時(shí)候會(huì)臨時(shí)啟動(dòng)SerialOld GC來重新進(jìn)行老年代的收集,這樣的話停頓的時(shí)間就會(huì)加長。

  •  標(biāo)記-清除算法導(dǎo)致的空間碎片 CMS是一款基于“標(biāo)記-清除”算法實(shí)現(xiàn)的收集器,這意味著收集結(jié)束時(shí)會(huì)有大量空間碎片產(chǎn)生??臻g碎片過多時(shí),將會(huì)給大對(duì)象分配帶來很大麻煩,往往出現(xiàn)老年代空間剩余,但無法找到足夠大連續(xù)空間來分配當(dāng)前對(duì)象。為了解決這個(gè)問題CMS提供了一個(gè)參數(shù)-XX:+UseCMSCompactAtFullCollecion,如果啟用,在Full GC的時(shí)候開啟內(nèi)存碎片整理合并過程,由于內(nèi)存碎片整理的過程無法并行執(zhí)行,所以停頓的時(shí)間會(huì)加長??紤]到每次FullGC都要進(jìn)行內(nèi)存碎片合并不是很合適,所以CMS又提供了另一個(gè)參數(shù)-XX:CMSFullGCsBeforeCompaction來控制執(zhí)行多少次不帶碎片整理的FullGC之后,來一次帶碎片整理GC

G1收集器

G1是一款面向服務(wù)端應(yīng)用的垃圾回收器。

  •  并行與并發(fā):與CMS類似,充分里用多核CPU的優(yōu)勢(shì),G1仍然可以不暫停用戶線程執(zhí)行垃圾收集工作

  •  分代收集:分代的概念依然在G1保留,當(dāng)時(shí)它不需要和其他垃圾收集器配合使用,可以獨(dú)立管理整個(gè)堆內(nèi)存

  •  空間的整合:G1整體上采用的是標(biāo)記-整理算法,從局部(Region)采用的是復(fù)制算法,這兩種算法都意味著G1不需要進(jìn)行內(nèi)存碎片整理

  •  可預(yù)測(cè)的停頓:能夠讓用戶指定在時(shí)間片段內(nèi),消耗在垃圾收集的時(shí)間不超過多長時(shí)間。

Region

雖然在G1中依然保留了新生代和老年代的概念,但是采用的是一種完全不同的方式來組織堆內(nèi)存,它把整個(gè)堆內(nèi)存分割成了很多大小相同的區(qū)域(Region),并且新生代和老年代在物理上也不是連續(xù)的內(nèi)存區(qū)域,請(qǐng)看下圖:

面試官常問的垃圾回收器有哪些

每個(gè)Region被標(biāo)記了E、S、O和H,其中H是以往算法中沒有的,它代表Humongous,這表示這些Region存儲(chǔ)的是巨型對(duì)象,當(dāng)新建對(duì)象大小超過Region大小一半時(shí),直接在新的一個(gè)或多個(gè)連續(xù)Region中分配,并標(biāo)記為H。Region區(qū)域的內(nèi)存大小可以通過-XX:G1HeapRegionSize參數(shù)指定,大小區(qū)間只能是2的冪次方,如:1M、2M、4M、8M

G1的GC模式

  •  新生代GC:與其他新生代收集器類似,對(duì)象優(yōu)先在eden region分配,如果eden region內(nèi)存不足就會(huì)觸發(fā)新生代的GC,把存活的對(duì)象安置在survivor region,或者晉升到old region

  •  混合GC:當(dāng)越來越多的對(duì)象晉升到了old region,當(dāng)老年代的內(nèi)存使用率達(dá)到某個(gè)閾值就會(huì)觸發(fā)混合GC,可以通過參數(shù)-XX:InitiatingHeapOccupancyPercent設(shè)置閾值百分比,此參數(shù)與CMS中-XX:CMSInitiatingoccupancyFraction的功能類似;混合GC會(huì)回收新生代和部分老年代內(nèi)存,注意是部分老年代而不是全部老年代;G1會(huì)跟蹤每個(gè)Region中的垃圾回收價(jià)值,在用戶指定的垃圾收集時(shí)間內(nèi)優(yōu)先回收價(jià)值最大的region

  •  Full GC:如果對(duì)象內(nèi)存分配速度過快,混合GC還未回收完成,導(dǎo)致老年代被填滿,就會(huì)觸發(fā)一次full gc,G1的full gc算法就是單線程執(zhí)行的serial old gc,此過程與CMS類似,會(huì)導(dǎo)致異常長時(shí)間的暫停時(shí)間,盡可能的避免full gc. 

到此,關(guān)于“面試官常問的垃圾回收器有哪些”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

jvm
AI