Jvm的內(nèi)存分配與回收策略

Java技術(shù)體系的自動(dòng)內(nèi)存管理,最根本的目標(biāo)是自動(dòng)化地解決兩個(gè)問題:自動(dòng)給對(duì)象分配內(nèi)存和自動(dòng)回收分配給對(duì)象的內(nèi)存。下面就會(huì)介紹一下關(guān)于分配內(nèi)存的一些原則等等。(后續(xù)會(huì)補(bǔ)充相關(guān)參數(shù)的使用和堆的情況)

對(duì)象優(yōu)先在Eden區(qū)分配

大多數(shù)情況下,對(duì)象在新生代Eden區(qū)中分配。當(dāng)Eden區(qū)沒有足夠空間進(jìn)行分配時(shí),虛擬機(jī)將發(fā)起一次Minor GC,然后再進(jìn)行分配。

大對(duì)象直接進(jìn)入

大對(duì)象就是指需要大量連續(xù)內(nèi)存空間的Java對(duì)象,最典型的大對(duì)象便是那種很長(zhǎng)的字符串,或者元素?cái)?shù)量很龐大的數(shù)組!

之所以大對(duì)象要在老年代中分配是因?yàn)榇髮?duì)象如果在新生代分配空間時(shí),它容易導(dǎo)致內(nèi)存明明還有不少空間時(shí)提前觸發(fā)垃圾收集,以獲取足夠的空間來安置他們,新生代使用復(fù)制算法,當(dāng)復(fù)制時(shí)候大對(duì)象也意味著高額的內(nèi)存復(fù)制開銷。HotSpot虛擬機(jī)提供了-XX:PretenureSizeThreshold參數(shù),指定大于該設(shè)置值的對(duì)象直接在老年代分配,這樣做的目的就是避免在Eden區(qū)及兩個(gè)Survivor區(qū)之間來回復(fù)制,產(chǎn)生大量的內(nèi)存復(fù)制操作。

長(zhǎng)期存活的對(duì)象將進(jìn)入老年代

我們之前在介紹GC算法標(biāo)記-復(fù)制的時(shí)候,在新生代長(zhǎng)期存活的對(duì)象,就會(huì)進(jìn)入老年代。為做到一點(diǎn),虛擬機(jī)給每個(gè)對(duì)象定義了一個(gè)對(duì)象年齡(Age)計(jì)數(shù)器,存儲(chǔ)在對(duì)象頭。在新生代第一次被收集的時(shí)候,對(duì)象會(huì)從Eden區(qū)復(fù)制到Survivor區(qū),后面會(huì)繼續(xù)在兩個(gè)Survivor區(qū)里面來回復(fù)制。每在Survivor區(qū)里面熬過一次收集,Age就會(huì)加1。當(dāng)Age達(dá)到默認(rèn)的15的時(shí)候,就會(huì)晉升到老年代!

對(duì)象晉升老年代的年齡閾值,可以通過參數(shù)-XX:MaxTenuringThreshold設(shè)置。

動(dòng)態(tài)對(duì)象年齡判斷

為了適應(yīng)不同內(nèi)存狀況,虛擬機(jī)不要求對(duì)象年齡達(dá)到閾值才能晉升老年代,如果在 Survivor 中相同年齡所有對(duì)象大小的總和大于 Survivor 的一半,年齡不小于該年齡的對(duì)象就可以直接進(jìn)入老年代。

空間分配擔(dān)保

我們的空間分配擔(dān)保是指在發(fā)生Minor GC之前,虛擬機(jī)必須先檢查老年代最大可用的連續(xù)空間是否大于新生代所有對(duì)象總空間,如果這個(gè)條件成立,那么這一次Minor GC可以確保是安全的!

如果條件不成立,虛擬機(jī)會(huì)查看 -XX:HandlePromotionFailure 參數(shù)設(shè)置的是否允許擔(dān)保失敗,如果允許會(huì)繼續(xù)檢查老年代最大可用連續(xù)空間是否大于歷次晉升老年代對(duì)象的平均大小,如果滿足將冒險(xiǎn)嘗試一次 Minor GC,否則改成一次 FullGC。

為什么需要空間分配擔(dān)保呢?

這是因?yàn)橐紤]到我們的新生代是使用一個(gè)Survivor空間來作為輪換備份,在經(jīng)歷多次Minor GC后,存在極端情況就是內(nèi)存回收后新生代中所有對(duì)象都存活。我們是需要保證老年代有足夠大的空間來容納這些Survivor區(qū)無法容納的存活的對(duì)象,如果無法容納就會(huì)觸發(fā)Full GC!而設(shè)置允許冒險(xiǎn)其實(shí)就是一種賭概率的方式,賭老年代可以容納!

參考資料

深入理解Java虛擬機(jī)(第三版)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容