如何理解GC知識(shí)點(diǎn)CMS

如何理解GC知識(shí)點(diǎn)CMS,相信很多沒有經(jīng)驗(yàn)的人對(duì)此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個(gè)問題。

在成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作過程中,需要針對(duì)客戶的行業(yè)特點(diǎn)、產(chǎn)品特性、目標(biāo)受眾和市場(chǎng)情況進(jìn)行定位分析,以確定網(wǎng)站的風(fēng)格、色彩、版式、交互等方面的設(shè)計(jì)方向。創(chuàng)新互聯(lián)建站還需要根據(jù)客戶的需求進(jìn)行功能模塊的開發(fā)和設(shè)計(jì),包括內(nèi)容管理、前臺(tái)展示、用戶權(quán)限管理、數(shù)據(jù)統(tǒng)計(jì)和安全保護(hù)等功能。

今天準(zhǔn)備將之前沒有細(xì)講的部分進(jìn)行補(bǔ)充,首先要提到的就是垃圾收集器。

基礎(chǔ)的回收方式有三種:清除壓縮、復(fù)制,衍生出來的垃圾收集器有:

Serial 收集器

新生代收集器,使用停止復(fù)制算法,使用一個(gè)線程進(jìn)行 GC ,串行,其它工作線程暫停。

使用-XX:+UseSerialGC開關(guān)來控制使用Serial + Serial Old模式運(yùn)行進(jìn)行內(nèi)存回收(這也是虛擬機(jī)在 Client 模式下運(yùn)行的默認(rèn)值)。

ParNew 收集器

新生代收集器,使用停止復(fù)制算法,Serial 收集器的多線程版,用多個(gè)線程進(jìn)行 GC ,并行,其它工作線程暫停,關(guān)注縮短垃圾收集時(shí)間。

使用-XX:+UseParNewGC開關(guān)來控制使用ParNew + Serial Old收集器組合收集內(nèi)存;使用-XX:ParallelGCThreads來設(shè)置執(zhí)行內(nèi)存回收的線程數(shù)。

Parallel Scavenge 收集器

新生代收集器,使用停止復(fù)制算法,關(guān)注 CPU 吞吐量,即運(yùn)行用戶代碼的時(shí)間/總時(shí)間,比如:JVM 運(yùn)行 100 分鐘,其中運(yùn)行用戶代碼 99 分鐘,垃 圾收集 1 分鐘,則吞吐量是 99% ,這種收集器能最高效率的利用 CPU ,適合運(yùn)行后臺(tái)運(yùn)算(其他關(guān)注縮短垃圾收集時(shí)間的收集器,如 CMS ,等待時(shí)間很少,所以適 合用戶交互,提高用戶體驗(yàn))。

使用-XX:+UseParallelGC開關(guān)控制使用Parallel Scavenge + Serial Old收集器組合回收垃圾(這也是在 Server 模式下的默認(rèn)值);使用-XX:GCTimeRatio來設(shè)置用戶執(zhí)行時(shí)間占總時(shí)間的比例,默認(rèn) 99 ,即 1% 的時(shí)間用來進(jìn)行垃圾回收。使用-XX:MaxGCPauseMillis設(shè)置 GC 的最大停頓時(shí)間(這個(gè)參數(shù)只對(duì) Parallel Scavenge 有效),用開關(guān)參數(shù)-XX:+UseAdaptiveSizePolicy可以進(jìn)行動(dòng)態(tài)控制,如自動(dòng)調(diào)整 Eden / Survivor 比例,老年代對(duì)象年齡,新生代大小等,這個(gè)參數(shù)在 ParNew 下沒有。

Serial Old 收集器

老年代收集器,單線程收集器,串行,使用標(biāo)記-整理算法,使用單線程進(jìn)行GC,其它工作線程暫停(注意:在老年代中進(jìn)行標(biāo)記-整理算法清理,也需要暫停其它線程),在JDK1.5之前,Serial Old 收集器與 ParallelScavenge 搭配使用。 >整理的方法是 Sweep (清除)和 Compact (壓縮),清除是將廢棄的對(duì)象干掉,只留幸存的對(duì)象,壓縮是移動(dòng)對(duì)象,將空間填滿保證內(nèi)存分為2塊,一塊全是對(duì)象,一塊空閑),

Parallel Old 收集器

老年代收集器,多線程,并行,多線程機(jī)制與 Parallel Scavenge 差不錯(cuò),使用標(biāo)記-整理算法,在 Parallel Old 執(zhí)行時(shí),仍然需要暫停其它工作線程。 >Parallel Old 收集器的整理,與 Serial Old 不同,這里的整理是Copy(復(fù)制)和Compact(壓縮),復(fù)制的意思就是將幸存的對(duì)象復(fù)制到預(yù)先準(zhǔn)備好的區(qū)域,而不是像Sweep(清除)那樣清除廢棄的對(duì)象。

Parallel Old 在多核計(jì)算中很有用。 Parallel Old 出現(xiàn)后(JDK 1.6),與 Parallel Scavenge 配合有很好的效果,充分體現(xiàn) Parallel Scavenge 收集器吞吐量?jī)?yōu)先的效果。使用-XX:+UseParallelOldGC開關(guān)控制使用Parallel Scavenge + Parallel Old組合收集器進(jìn)行收集。

CMS

全稱 Concurrent Mark Sweep,老年代收集器,致力于獲取最短回收停頓時(shí)間(即縮短垃圾回收的時(shí)間),使用標(biāo)記-清除算法,多線程,優(yōu)點(diǎn)是并發(fā)收集(用戶線程可以和 GC 線程同時(shí)工作),停頓小。

使用-XX:+UseConcMarkSweepGC進(jìn)行ParNew + CMS + Serial Old進(jìn)行內(nèi)存回收,優(yōu)先使用ParNew + CMS(原因見后面),當(dāng)用戶線程內(nèi)存不足時(shí),采用備用方案Serial Old收集。

如何開始

首先來看一下 CMS 是在什么情況下進(jìn)行 GC:

  1. 首先 JVM 根據(jù)-XX:CMSInitiatingOccupancyFraction-XX:+UseCMSInitiatingOccupancyOnly來決定什么時(shí)間開始垃圾收集。

  2. 如果設(shè)置了-XX:+UseCMSInitiatingOccupancyOnly,那么只有當(dāng)老年代占用確實(shí)達(dá)到了-XX:CMSInitiatingOccupancyFraction參數(shù)所設(shè)定的比例時(shí)才會(huì)觸發(fā) CMS GC。

  3. 如果沒有設(shè)置-XX:+UseCMSInitiatingOccupancyOnly,那么系統(tǒng)會(huì)根據(jù)統(tǒng)計(jì)數(shù)據(jù)自行決定什么時(shí)候觸發(fā) CMS GC。因此有時(shí)會(huì)遇到設(shè)置了 80% 比例才 CMS GC,但是 50% 時(shí)就已經(jīng)觸發(fā)了,就是因?yàn)檫@個(gè)參數(shù)沒有設(shè)置的原因。

具體執(zhí)行

CMS GC 的執(zhí)行過程,具體來說就是:

初始標(biāo)記(CMS-initial-mark)

該階段是 stop the world 階段,因此此階段標(biāo)記的對(duì)象只是從 root 集最直接可達(dá)的對(duì)象。

此階段會(huì)打印 1 條日志:CMS-initial-mark:961330K(1572864K),指標(biāo)記時(shí),老年代的已用空間和總空間

并發(fā)標(biāo)記(CMS-concurrent-mark)

此階段是和應(yīng)用線程并發(fā)執(zhí)行的,所謂并發(fā)收集器指的就是這個(gè),主要作用是標(biāo)記可達(dá)的對(duì)象,此階段不需要用戶線程停頓。

此階段會(huì)打印 2 條日志:CMS-concurrent-mark-start,CMS-concurrent-mark

預(yù)清理(CMS-concurrent-preclean)

此階段主要是進(jìn)行一些預(yù)清理,因?yàn)闃?biāo)記和應(yīng)用線程是并發(fā)執(zhí)行的,因此會(huì)有些對(duì)象的狀態(tài)在標(biāo)記后會(huì)改變,此階段正是解決這個(gè)問題。因?yàn)橹蟮?CMS-remark 階段也會(huì) stop the world,為了使暫停的時(shí)間盡可能的小,也需要 preclean 階段先做一部分工作以節(jié)省時(shí)間。

此階段會(huì)打印 2 條日志:CMS-concurrent-preclean-start,CMS-concurrent-preclean

可控預(yù)清理(CMS-concurrent-abortable-preclean)

此階段的目的是使 CMS GC 更加可控一些,作用也是執(zhí)行一些預(yù)清理,以減少 CMS-remark 階段造成應(yīng)用暫停的時(shí)間。

此階段涉及幾個(gè)參數(shù):

    -XX:CMSMaxAbortablePrecleanTime:當(dāng) abortable-preclean 階段執(zhí)行達(dá)到這個(gè)時(shí)間時(shí)才會(huì)結(jié)束。
    -XX:CMSScheduleRemarkEdenSizeThreshold(默認(rèn)2m):控制 abortable-preclean 階段什么時(shí)候開始執(zhí)行,即當(dāng)年輕代使用達(dá)到此值時(shí),才會(huì)開始 abortable-preclean 階段。
    -XX:CMSScheduleRemarkEdenPenetratio(默認(rèn)50%):控制 abortable-preclean 階段什么時(shí)候結(jié)束執(zhí)行。

此階段會(huì)打印 3 條日志:CMS-concurrent-abortable-preclean-start,CMS-concurrent-abortable-preclean,CMS:abort preclean due to time XXX

重新標(biāo)記(CMS-remark)

此階段暫停應(yīng)用線程,停頓時(shí)間比并發(fā)標(biāo)記小得多,但比初始標(biāo)記稍長(zhǎng),因?yàn)闀?huì)對(duì)所有對(duì)象進(jìn)行重新掃描并標(biāo)記。

此階段會(huì)打印以下日志:

  1. YG occupancy:964861K(2403008K),指執(zhí)行時(shí)年輕代的情況。

  2. CMS remark:961330K(1572864K),指執(zhí)行時(shí)老年代的情況。

  3. 此外,還打印出了弱引用處理、類卸載等過程的耗時(shí)。

并發(fā)清除(CMS-concurrent-sweep)

此階段進(jìn)行并發(fā)的垃圾清理。

并發(fā)重設(shè)狀態(tài)等待下次CMS的觸發(fā)(CMS-concurrent-reset)

此階段是為下一次 CMS GC 重置相關(guān)數(shù)據(jù)結(jié)構(gòu)。

總結(jié)

CMS 的收集過程,概括一下就是:2 次標(biāo)記,2 次預(yù)清除,1 次重新標(biāo)記,1 次清除。

在CMS清理過程中,只有初始標(biāo)記和重新標(biāo)記需要短暫停頓用戶線程,并發(fā)標(biāo)記和并發(fā)清除都不需要暫停用戶線程,因此效率很高,很適合高交互的場(chǎng)合。

CMS也有缺點(diǎn),它需要消耗額外的 CPU 和內(nèi)存資源。在 CPU 和內(nèi)存資源緊張,會(huì)加重系統(tǒng)負(fù)擔(dān)(CMS 默認(rèn)啟動(dòng)線程數(shù)為( CPU數(shù)量 + 3 ) / 4 )。

另外,在并發(fā)收集過程中,用戶線程仍然在運(yùn)行,仍然產(chǎn)生內(nèi)存垃圾,所以可能產(chǎn)生“浮動(dòng)垃圾”(本次無法清理,只能下一次Full GC才清理)。因此在 GC 期間,需要預(yù)留足夠的內(nèi)存給用戶線程使用。

所以使用 CMS 的收集器并不是老年代滿了才觸發(fā) Full GC ,而是在使用了一大半(默認(rèn) 68% ,即 2/3 ,使用-XX:CMSInitiatingOccupancyFraction來設(shè)置)的時(shí)候就要進(jìn)行 Full GC。如果用戶線程消耗內(nèi)存不是特別大,可以適當(dāng)調(diào)高-XX:CMSInitiatingOccupancyFraction以降低 GC 次數(shù),提高性能。如果預(yù)留的用戶線程內(nèi)存不夠,則會(huì)觸發(fā) Concurrent Mode Failure,此時(shí),將觸發(fā)備用方案:使用 Serial Old 收集器進(jìn)行收集,但這樣停頓時(shí)間就長(zhǎng)了,因此-XX:CMSInitiatingOccupancyFraction不宜設(shè)的過大。

還有,CMS 采用的是標(biāo)記-清除算法,會(huì)導(dǎo)致內(nèi)存碎片的產(chǎn)生,可以使用-XX:+UseCMSCompactAtFullCollection來設(shè)置是否在 Full GC 之后進(jìn)行碎片整理,用-XX:CMSFullGCsBeforeCompaction來設(shè)置在執(zhí)行多少次不壓縮的 Full GC 之后,來一次帶壓縮的 Full GC。

并發(fā)和并行

并發(fā)收集: >指用戶線程與GC線程同時(shí)執(zhí)行(不一定是并行,可能交替,但總體上是在同時(shí)執(zhí)行的),不需要停頓用戶線程(其實(shí)在 CMS 中用戶線程還是需要停頓的,只是非常短,GC 線程在另一個(gè) CPU 上執(zhí)行);

并行收集: >指多個(gè) GC 線程并行工作,但此時(shí)用戶線程是暫停的;

所以,Serial 是串行的,Parallel 收集器是并行的,而 CMS 收集器是并發(fā)的。

看完上述內(nèi)容,你們掌握如何理解GC知識(shí)點(diǎn)CMS的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!

分享題目:如何理解GC知識(shí)點(diǎn)CMS
文章分享:http://www.muchs.cn/article30/jdoeso.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供、企業(yè)建站、域名注冊(cè)、Google、網(wǎng)站排名、標(biāo)簽優(yōu)化

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站建設(shè)

網(wǎng)站設(shè)計(jì)公司知識(shí)