您好,登錄后才能下訂單哦!
Java虛擬機(jī)的內(nèi)存分配策略是怎樣的,很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。
Java技術(shù)體系中的自動(dòng)內(nèi)存管理可以歸結(jié)為自動(dòng)化的解決了兩個(gè)問題:給對(duì)象分配內(nèi)存和回收分配給對(duì)象的內(nèi)存。
對(duì)象的內(nèi)存分分配主要是指堆上分配(也可棧上分配),對(duì)象主要分配在新生代Eden區(qū),如果啟動(dòng)了本地線程分配緩沖,則按照線程優(yōu)先在TLAB上分配。少數(shù)情況下也會(huì)直接分配在老年代,分配的規(guī)則不固定,取決于垃圾回收器組合以及JVM中與內(nèi)存相關(guān)參數(shù)的設(shè)置。
我們以Serial/Serial Old收集器為例進(jìn)行介紹。
大多數(shù)情況下,對(duì)象在新生代的Eden區(qū)中分配,當(dāng)Eden區(qū)沒有足夠空間進(jìn)行分配時(shí),虛擬機(jī)將會(huì)發(fā)起一次Minor GC。
大對(duì)象是指需要大量連續(xù)內(nèi)存空間的Java對(duì)象,典型大對(duì)象有長(zhǎng)字符串和數(shù)組,大對(duì)象對(duì)虛擬機(jī)的內(nèi)存分配來說是一個(gè)壞消息,寫程序時(shí)還要避免創(chuàng)建一些朝生夕死的短命大對(duì)象,經(jīng)常出現(xiàn)大對(duì)象容易導(dǎo)致內(nèi)存還有不少空間時(shí)就提前觸發(fā)垃圾收集以獲取足夠的連續(xù)空間來安置他們。
虛擬機(jī)提供-XX:PretenureSizeThreshold參數(shù),令大于這個(gè)設(shè)置值的對(duì)象直接在老年代分配,這樣避免再Eden及兩個(gè)Survivor區(qū)間發(fā)生大量的內(nèi)存復(fù)制,這個(gè)參數(shù)只對(duì)Serial和ParNew兩款收集器有效,如果遇到必須使用此參數(shù)的場(chǎng)合,可以考慮ParNew加CMS的組合。
大對(duì)象直接在老年代進(jìn)行分配的目的是避免在Eden區(qū)和兩個(gè)Survivor區(qū)之間發(fā)生大量的內(nèi)存復(fù)制。
虛擬機(jī)給每個(gè)對(duì)象定義了一個(gè)對(duì)象年齡計(jì)數(shù)器,如果對(duì)象在Eden出生并經(jīng)過第一次Minor GC后仍然存活,并且能被Survivor容納的話,將被移動(dòng)到Survivor空間中,并且對(duì)象年齡設(shè)為1,對(duì)象在Survivor區(qū)中每熬過一次Minor GC,年齡就增加1歲,當(dāng)它的年齡增加到一定程度(默認(rèn)為15歲),就會(huì)被晉升到老年代中,可以通過-XX:MaxTenuringThreshold參數(shù)來設(shè)置年齡閾值。
為了能更好的適應(yīng)不同程序的內(nèi)存情況,虛擬機(jī)不是永遠(yuǎn)的要求對(duì)象的年齡必須達(dá)到閾值才能晉升老年代;如果在Survivor區(qū)中的相同年齡所有對(duì)象大小的總和大于Survivor空間的一半,年齡大于或者等于該年齡的對(duì)象就可以直接進(jìn)入老年代,無須等到-XX:MaxTenuringThreshold 中要求的年齡。
關(guān)于分配擔(dān)保機(jī)制JDK6前后有差別的。
當(dāng)發(fā)生Minor GC時(shí),JVM會(huì)首先檢查老年代最大的可用連續(xù)空間是否大于新生代所有對(duì)象的總和,如果大于,那么這次Minor GC是安全的,如果不大于的話,JVM就需要判斷HandlePromotionFailure是否允許空間分配擔(dān)保。
如果允許擔(dān)保失敗,那么JVM會(huì)繼續(xù)檢查老年代最大的可用連續(xù)空間是否大于歷次晉升到老年代的對(duì)象的平均大?。?/p>
如果大于,則正常進(jìn)行一次YGC,盡管有風(fēng)險(xiǎn)(因?yàn)榕袛嗟氖瞧骄笮。锌赡苓@次的晉升對(duì)象比平均值大很多);
如果小于,或者HandlePromotionFailure設(shè)置不允許空間分配擔(dān)保,這時(shí)要進(jìn)行一次FGC。
對(duì)以上的步驟歸納一下,先看老年代的可用空間能否容下新生代的所有對(duì)象,不能的話看是否開啟了分配擔(dān)保機(jī)制,允許就先執(zhí)行Minor GC,否則直接進(jìn)行Full GC。大部分情況下還是會(huì)將HandlePromotionFailure開啟分配擔(dān)保,避免頻繁Full GC。
HandlePromotionFailure不再影響到虛擬機(jī)的空間分配擔(dān)保策略,變?yōu)橹灰夏甏倪B續(xù)空間大于新生代對(duì)象總大小或歷次晉升的平均大小就會(huì)進(jìn)行Minor GC,否則將進(jìn)行Full GC。
Minor GC和Major GC/Full GC:
新生代GC(Minor GC:縮寫YGC,指發(fā)生在新生代的垃圾回收動(dòng)作,因?yàn)镴ava對(duì)象大多都具備朝生夕滅的特性,所以Monir GC非常頻繁,一般回收速度也比較快。
老年代GC(Major GC/Full GC):指發(fā)生在老年代的GC,出現(xiàn)了Major GC,經(jīng)常會(huì)伴隨至少一次的Minor GC(但并非絕對(duì)的,在Parallel Scavenge)收集器的收集策略里就有直接進(jìn)行Major GC的策略選擇過程。Major GC的速度一般比Major GC慢10倍以上。
看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝您對(duì)億速云的支持。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。