溫馨提示×

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

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

JVM中垃圾回收的判定標(biāo)準(zhǔn)和內(nèi)存相關(guān)參數(shù)介紹

發(fā)布時(shí)間:2021-09-06 17:56:32 來源:億速云 閱讀:157 作者:chen 欄目:大數(shù)據(jù)

這篇文章主要講解了“JVM中垃圾回收的判定標(biāo)準(zhǔn)和內(nèi)存相關(guān)參數(shù)介紹”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“JVM中垃圾回收的判定標(biāo)準(zhǔn)和內(nèi)存相關(guān)參數(shù)介紹”吧!

JVM中垃圾回收的判定標(biāo)準(zhǔn)

最終目的是將內(nèi)存中無用的對(duì)象回收掉。具體的判定方法有:

  • 引用計(jì)數(shù)法,不采用,指的是維護(hù)對(duì)象被引用的次數(shù),次數(shù)為0則意味著是垃圾。

  • 可達(dá)性算法-GC Roots tracing,指的是從GC Roots開始往下遍歷所有引用的對(duì)象,(每個(gè)GC Root就是一個(gè)樹狀圖),所有被引用到的對(duì)象就是需要存活的對(duì)象,其他對(duì)象可以被回收。GC Root指的是,虛擬機(jī)棧(棧幀中的本地變量表)中引用的對(duì)象,方法區(qū)中非基本類型的類靜態(tài)變量(一個(gè)地址)所引用的對(duì)象,本地方法棧中JNI(即一般說的Native方法)引用的對(duì)象。

JVM中內(nèi)存相關(guān)參數(shù)

  • -Xms Java堆內(nèi)存初始大小

  • -Xmx Java堆內(nèi)存最大大小

  • -Xmn Java堆內(nèi)存中的新生代大小,扣除它就是老年代大小

  • -XX:PermSize(1.8之后:-XX:MetaspaceSize) 永久代初始大小

  • -XX:MaxPerSize(1.8之后:-XX:MaxMetaspaceSize) 永久代最大大小

  • -Xss 每個(gè)線程的棧內(nèi)存大小

注:通常情況下,Xms和Xmx,-XX:PermSize和-XX:MaxPerSize都會(huì)設(shè)置為一樣。

  • -XX:MaxTenuringThreshold 多少歲進(jìn)入老年代-默認(rèn)15

  • -XX:PretenureSizeThreshold 超過多少字節(jié)的大對(duì)象直接進(jìn)入老年代

  • -XX:HandlePromotionFailure MinorGC時(shí),如果老年代剩余空間小于新生代對(duì)象總大小,但是如果大于之前平均進(jìn)入老年代對(duì)象的大小,是否嘗試進(jìn)行MinorGC(默認(rèn)開啟)

  • -XX:SurvivorRatio=8 Eden區(qū)的比例

上面看不懂的參數(shù)不要深究,等下提到回過頭再來看,這里只是將所有參數(shù)羅列出來方便查找。

JVM中的內(nèi)存分代模型

JVM中,將對(duì)象在內(nèi)存中分為了三代:

  • 年輕代:很快被回收的對(duì)象,存在于堆,具體還在內(nèi)存中分為了1個(gè)eden區(qū),和2個(gè)survivor區(qū)。

  • 老年代:長期存在的對(duì)象,存在于堆

  • 永久代:指的就是方法區(qū)(存放Class元數(shù)據(jù)),回收條件較苛刻,需滿足:該類所有實(shí)例對(duì)象所有已經(jīng)從堆內(nèi)存被回收,該類classLoader已經(jīng)被回收,該類Class對(duì)象沒有任何引用

為什么要分代勒,因?yàn)獒槍?duì)每個(gè)年齡代,都有不同的垃圾回收算法,以及內(nèi)存分配機(jī)制。如果將所有對(duì)象放在一起,第一是會(huì)造成頻繁遍歷判斷回收的開銷,第二是會(huì)造成復(fù)制、移動(dòng)的開銷,為什么會(huì)有復(fù)制、移動(dòng),因?yàn)榛厥諆?nèi)存必然會(huì)造成內(nèi)存碎片,而內(nèi)存碎片會(huì)導(dǎo)致空間浪費(fèi),所以必須通過復(fù)制、移動(dòng)來清理隨便,使得空閑內(nèi)存連續(xù)。

JVM中具體的內(nèi)存分配模型

JVM中垃圾回收的判定標(biāo)準(zhǔn)和內(nèi)存相關(guān)參數(shù)介紹

如上圖,至于年輕代為什么要如此分配,與特定的回收算法有關(guān)。

對(duì)象在內(nèi)存分代中如何流轉(zhuǎn)

年輕代

大部分對(duì)象剛創(chuàng)建的時(shí)候都會(huì)分配在年輕代的Eden區(qū),只要年輕代空間不夠就會(huì)觸發(fā)MinorGC(只回收年輕代內(nèi)存),minorGC采取復(fù)制算法進(jìn)行回收,當(dāng)JVM運(yùn)行觸發(fā)第一輪minorGC時(shí),會(huì)將eden區(qū)存活的對(duì)象先復(fù)制到一個(gè)suprivor區(qū)。然后刪除eden區(qū)對(duì)象,當(dāng)觸發(fā)下一輪minorGC時(shí),又把suprivor區(qū)和eden區(qū)的存活的對(duì)象轉(zhuǎn)移到另一個(gè)suprivor區(qū),然后刪除這兩個(gè)區(qū)的所有對(duì)象。依次類推。至于為什么要用復(fù)制算法,包括老年代的標(biāo)記整理算法,這是考慮到了避免內(nèi)存碎片。如果對(duì)象內(nèi)存不連續(xù),會(huì)造成很多的空間浪費(fèi)。

老年代

老年代的對(duì)象都是從年輕代根據(jù)一定的規(guī)則流轉(zhuǎn)過來的。 具體有幾類流轉(zhuǎn)方式:

  • 超過指定年齡(參數(shù)-XX:MaxTenuringThreshold 配置,默認(rèn)15),這里年齡指的是沒有被垃圾回收,存活下來一次理解為增加一歲。流轉(zhuǎn)到老年代。

  • 大對(duì)象直接進(jìn)入,超過參數(shù)指定字節(jié)數(shù)(-XX:PretenureSizeThreshold)設(shè)置的字節(jié)數(shù)的大對(duì)象會(huì)直接進(jìn)入老年代,這是因?yàn)閷?duì)象越大,復(fù)制開銷就越大。

  • 動(dòng)態(tài)年齡判斷規(guī)則進(jìn)入,意思是不一定要到指定年齡再流轉(zhuǎn)到15,如果某一年齡以上的對(duì)象到達(dá)一定大小,也會(huì)提前進(jìn)入老年代。當(dāng)躲過一輪GC的對(duì)象加起來超過surrvivor區(qū)50%,如年齡1+年齡2+年齡n一直累加,直到年齡n的時(shí)候發(fā)現(xiàn)加起來超過了surrvivor空間的50%,則年齡n以上的對(duì)象直接進(jìn)入老年代

  • minorGC發(fā)生時(shí),suprivor區(qū)放不下,則所有存活對(duì)象轉(zhuǎn)移到老年代。這里涉及一個(gè)老年代分配擔(dān)保規(guī)則,指的是每次MinorGC發(fā)生時(shí),都會(huì)判斷老年代可用內(nèi)存大不大于,年輕代存活對(duì)象內(nèi)存之和,如果大于則直接進(jìn)行minorGC,如果小于則要看參數(shù)XX:HandlePromotionFailure是否啟用(默認(rèn)啟用),如果啟用則對(duì)老年代這次需要承載的轉(zhuǎn)移對(duì)象內(nèi)存進(jìn)行預(yù)估(取前面minorGC被轉(zhuǎn)移的平均內(nèi)存大?。?,若大于則也進(jìn)行MinorGC,若意料狀況外轉(zhuǎn)移內(nèi)存超出了老年代可用空間,則進(jìn)行FullGC,若fullGC還是不夠,則拋出OOM錯(cuò)誤。FullGC是采取的標(biāo)記整理算法,指的是移動(dòng)存活對(duì)象,讓內(nèi)存連續(xù),然后刪除需要回收的對(duì)象,為什么使用標(biāo)記整理?因?yàn)檎J(rèn)為老年代對(duì)象存活幾率高,復(fù)制算法不劃算。

永久代

永久代存放的是元數(shù)據(jù)信息,當(dāng)類加載時(shí),類元數(shù)據(jù)信息寫入永久代,fullGC時(shí)永久代數(shù)據(jù)被回收,回收條件是:該類所有實(shí)例對(duì)象所有已經(jīng)從堆內(nèi)存被回收,該類classLoader已經(jīng)被回收,該類Class對(duì)象沒有任何引用。

附圖:

JVM中垃圾回收的判定標(biāo)準(zhǔn)和內(nèi)存相關(guān)參數(shù)介紹

談一個(gè)JVM優(yōu)化實(shí)例

現(xiàn)一個(gè)日處理量上億數(shù)據(jù)的計(jì)算系統(tǒng),不斷從Mysql和其他數(shù)據(jù)中間件中提取數(shù)據(jù)進(jìn)行計(jì)算處理。每分鐘執(zhí)行500次數(shù)據(jù)提取和計(jì)算任務(wù),每次任務(wù)處理耗時(shí)10秒,每次處理1萬條數(shù)據(jù)(每條數(shù)據(jù)20個(gè)字段),但是集群部署,共5臺(tái)機(jī)器,1臺(tái)機(jī)器每分鐘處理100次任務(wù),每臺(tái)機(jī)器是4核8G內(nèi)配置,JVM分了4G,3G堆內(nèi)存,1.5G年輕代,1.5G老年代。

JVM中垃圾回收的判定標(biāo)準(zhǔn)和內(nèi)存相關(guān)參數(shù)介紹

我們先來估算一下內(nèi)存占用:

  • 每條數(shù)據(jù)20個(gè)字段,可以估算一條數(shù)據(jù)為1KB大小左右

  • 每次計(jì)算1W條,那么一個(gè)任務(wù)占用內(nèi)存就是1KB*1W=10MB數(shù)據(jù)左右,一臺(tái)機(jī)器每分鐘處理100次任務(wù),暫用內(nèi)存約為1G左右,基本上一分鐘多點(diǎn)后Eden區(qū)就被占滿了。

實(shí)際生產(chǎn)環(huán)境是怎么樣的勒?

  • 一分鐘之后的第一次GC,此時(shí)的內(nèi)存情況:

JVM中垃圾回收的判定標(biāo)準(zhǔn)和內(nèi)存相關(guān)參數(shù)介紹

每個(gè)任務(wù)處理10S,意味著還有大概六分之一的數(shù)據(jù)應(yīng)該存活,算200M,但是200M放不進(jìn)Survivor區(qū),所以會(huì)嘗試往老年代放,老年代現(xiàn)在大于1.2G所以直接放就是了。

  • 每次MinorGC都會(huì)有大概200M進(jìn)入老年代,當(dāng)進(jìn)行到第三次時(shí)

JVM中垃圾回收的判定標(biāo)準(zhǔn)和內(nèi)存相關(guān)參數(shù)介紹

此時(shí)老年代可用容量小于年輕代對(duì)象總內(nèi)存,默認(rèn)判斷老年代剩余空間是否大于平均每次MinorGC轉(zhuǎn)移過來的老年代對(duì)象容量,這里是大于,所以還是繼續(xù)MInorGC。

  • 當(dāng)進(jìn)行到第八次時(shí)

JVM中垃圾回收的判定標(biāo)準(zhǔn)和內(nèi)存相關(guān)參數(shù)介紹

此時(shí)會(huì)觸發(fā)FullGC清理老年代,于是老年代的對(duì)象被全部清理掉了:

JVM中垃圾回收的判定標(biāo)準(zhǔn)和內(nèi)存相關(guān)參數(shù)介紹

  • 然后繼續(xù)回到原來的第一次,每8次進(jìn)行一次FullGC,也就是8分鐘進(jìn)行一次

優(yōu)化策略

  • 重新調(diào)整新生代老年代比例,擴(kuò)大新生代內(nèi)存為2GB,老年代1GB

此時(shí)一個(gè)Survivor區(qū)有200MB,每次MinorGC后都能存放的下存活對(duì)象,不用往老年代轉(zhuǎn)移(當(dāng)然還是有轉(zhuǎn)移,這只是避免了suprivor區(qū)過小被迫轉(zhuǎn)移的對(duì)象)。JVM優(yōu)化的策略最核心的就是減少FullGC次數(shù),因?yàn)閽呙鑼?duì)象多了一個(gè)老年代和永久代、永久代標(biāo)記算法略微復(fù)雜、老年代整理時(shí)由于對(duì)象較多比較慢的原因,F(xiàn)ullGC效率是遠(yuǎn)遠(yuǎn)低于MinorGC的,一般時(shí)間是minorGC的10倍以上。

感謝各位的閱讀,以上就是“JVM中垃圾回收的判定標(biāo)準(zhǔn)和內(nèi)存相關(guān)參數(shù)介紹”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)JVM中垃圾回收的判定標(biāo)準(zhǔn)和內(nèi)存相關(guān)參數(shù)介紹這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

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

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎ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