溫馨提示×

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

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

Java內(nèi)存分配與回收的策略是什么

發(fā)布時(shí)間:2022-03-17 15:51:37 來(lái)源:億速云 閱讀:164 作者:iii 欄目:大數(shù)據(jù)

本文小編為大家詳細(xì)介紹“Java內(nèi)存分配與回收的策略是什么”,內(nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“Java內(nèi)存分配與回收的策略是什么”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來(lái)學(xué)習(xí)新知識(shí)吧。

Java內(nèi)存分配與回收的策略是什么

Java內(nèi)存分配與回收的策略是什么

表3-4 垃圾收集相關(guān)的常用參數(shù)    加上-XX: + UseSerialGC

Java內(nèi)存分配與回收的策略是什么

Java內(nèi)存分配與回收的策略是什么

Java內(nèi)存分配與回收的策略是什么

對(duì)象的內(nèi)存分配,從概念上講,應(yīng)該都是在堆上分配(而實(shí)際上也有可能經(jīng)過(guò)即時(shí)編譯后被拆散為標(biāo)量類(lèi)型并間接地在棧上分配 [1] )。在經(jīng)典分代的設(shè)計(jì)下,新生對(duì)象通常會(huì)分配在新生代中,少數(shù)情況下(例如對(duì)象大小超過(guò)一定閾值)也可能會(huì)直接分配在老年代。對(duì)象分配的規(guī)則并不是固定的,《Java虛擬機(jī)規(guī)范》并未規(guī)定新對(duì)象的創(chuàng)建和存儲(chǔ)細(xì)節(jié),這取決于虛擬機(jī)當(dāng)前使用的是哪一種垃圾收集器,以及虛擬機(jī)中與內(nèi)存相關(guān)的參數(shù)的設(shè)定。

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

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

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

大對(duì)象就是指需要大量連續(xù)內(nèi)存空間的Java對(duì)象,最典型的大對(duì)象便是那種很長(zhǎng)的字符串,或者元素?cái)?shù)量很龐大的數(shù)組,本節(jié)例子中的byte[]數(shù)組就是典型的大對(duì)象。大對(duì)象對(duì)虛擬機(jī)的內(nèi)存分配來(lái)說(shuō)就是一個(gè)不折不扣的壞消息,比遇到一個(gè)大對(duì)象更加壞的消息就是遇到一群“朝生夕滅”的“短命大對(duì)象”,我們寫(xiě)程序的時(shí)候應(yīng)注意避免。

Java虛擬機(jī)中要避免大對(duì)象的原因是,在分配空間時(shí),它容易導(dǎo)致內(nèi)存明明還有不少空間時(shí)就提前觸發(fā)垃圾收集,以獲取足夠的連續(xù)空間才能安置好它們,而當(dāng)復(fù)

制對(duì)象時(shí),大對(duì)象就意味著高額的內(nèi)存復(fù)制開(kāi)銷(xiāo)。HotSpot虛擬機(jī)提供了-XX:PretenureSizeThreshold參數(shù),指定大于該設(shè)置值的對(duì)象直接在老年代分配,這樣做的目的就是避免在Eden區(qū)及兩個(gè)Survivor區(qū)之間來(lái)回復(fù)制,產(chǎn)生大量的內(nèi)存復(fù)制操作。

-XX:PretenureSizeThreshold參數(shù)只對(duì)Serial和ParNew兩款新生代收集器有效,HotSpot的其他新生代收集器,如Parallel Scavenge并不支持這個(gè)參數(shù)。如果必須使用此參數(shù)進(jìn)行調(diào)優(yōu),可考慮ParNew加CMS的收集器組合。

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

虛擬機(jī)給每個(gè)對(duì)象定義了一個(gè)對(duì)象年齡(Age)計(jì)數(shù)器,存儲(chǔ)在對(duì)象頭中,每熬過(guò)一次Minor GC,年齡就增加1歲,當(dāng)它的年齡增加到一定程

度(默認(rèn)為15),就會(huì)被晉升到老年代中。對(duì)象晉升老年代的年齡閾值,可以通過(guò)參數(shù)-XX:MaxTenuringThreshold設(shè)置。

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

為了能更好地適應(yīng)不同程序的內(nèi)存狀況,HotSpot虛擬機(jī)并不是永遠(yuǎn)要求對(duì)象的年齡必須達(dá)到-XX:MaxTenuringThreshold才能晉升老年代,如果在Survivor空間中相同年齡所有對(duì)象大小的總和大于Survivor空間的一半,年齡大于或等于該年齡的對(duì)象就可以直接進(jìn)入老年代,無(wú)須等到-XX:MaxTenuringThreshold中要求的年齡。

空間分配擔(dān)保

在發(fā)生Minor GC之前,虛擬機(jī)必須先檢查老年代最大可用的連續(xù)空間是否大于新生代所有對(duì)象總空間,如果這個(gè)條件成立,那這一次Minor GC可以確保是安全的。如果不成立,則虛擬機(jī)會(huì)先查看-XX:HandlePromotionFailure參數(shù)的設(shè)置值是否允許擔(dān)保失?。℉andle Promotion Failure);如果允許,那會(huì)繼續(xù)檢查老年代最大可用的連續(xù)空間是否大于歷次晉升到老年代對(duì)象的平均大小,如果大于,將嘗試進(jìn)行一次Minor GC,盡管這次Minor GC是有風(fēng)險(xiǎn)的;如果小于,或者-XX:HandlePromotionFailure設(shè)置不允許冒險(xiǎn),那這時(shí)就要改為進(jìn)行一次Full GC。

在JDK 6 Update 24之后,這個(gè)測(cè)試結(jié)果就有了差異,-XX:HandlePromotionFailure參數(shù)不會(huì)再影響到虛擬機(jī)的空間分配擔(dān)保策略,觀察OpenJDK中的源碼變化(見(jiàn)代碼清單3-12),雖然源碼中還定義了-XX:HandlePromotionFailure參數(shù),但是在實(shí)際虛擬機(jī)中已經(jīng)不會(huì)再使用它。JDK 6 Update 24之后的規(guī)則變?yōu)橹灰夏甏倪B續(xù)空間大于新生代對(duì)象總大小或者歷次晉升的平均大小,就會(huì)進(jìn)行Minor GC,否則將進(jìn)行Full GC。

讀到這里,這篇“Java內(nèi)存分配與回收的策略是什么”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識(shí)點(diǎn)還需要大家自己動(dòng)手實(shí)踐使用過(guò)才能領(lǐng)會(huì),如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注億速云行業(yè)資訊頻道。

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

免責(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)容。

AI