您好,登錄后才能下訂單哦!
1. 對(duì)象優(yōu)先在 Eden 分配
大多數(shù)情況下,對(duì)象在新生代 Eden 上分配,當(dāng) Eden 空間不夠時(shí),發(fā)起 Minor GC。
2. 大對(duì)象直接進(jìn)入老年代
大對(duì)象是指需要連續(xù)內(nèi)存空間的對(duì)象,最典型的大對(duì)象是那種很長(zhǎng)的字符串以及數(shù)組。
經(jīng)常出現(xiàn)大對(duì)象會(huì)提前觸發(fā)垃圾收集以獲取足夠的連續(xù)空間分配給大對(duì)象。
-XX:PretenureSizeThreshold,大于此值的對(duì)象直接在老年代分配,避免在 Eden 和 Survivor 之間的大量?jī)?nèi)存復(fù)制。
3. 長(zhǎng)期存活的對(duì)象進(jìn)入老年代
為對(duì)象定義年齡計(jì)數(shù)器,對(duì)象在 Eden 出生并經(jīng)過(guò) Minor GC 依然存活,將移動(dòng)到 Survivor 中,年齡就增加 1 歲,增加到一定年齡則移動(dòng)到老年代中。
-XX:MaxTenuringThreshold 用來(lái)定義年齡的閾值,默認(rèn)值為15。
4. 動(dòng)態(tài)對(duì)象年齡判定
虛擬機(jī)并不是永遠(yuǎn)要求對(duì)象的年齡必須達(dá)到 MaxTenuringThreshold 才能晉升老年代,如果在 Survivor 中相同年齡所有對(duì)象大小的總和大于 Survivor 空間的一半,則年齡大于或等于該年齡的對(duì)象可以直接進(jìn)入老年代,無(wú)需等到 MaxTenuringThreshold 中要求的年齡。
5. 空間分配擔(dān)保
在發(fā)生 Minor GC 之前,虛擬機(jī)先檢查老年代最大可用的連續(xù)空間是否大于新生代所有對(duì)象總空間,如果條件成立的話,那么 Minor GC 可以確認(rèn)是安全的。
如果不成立的話虛擬機(jī)會(huì)查看 HandlePromotionFailure 的值是否允許擔(dān)保失敗,如果允許那么就會(huì)繼續(xù)檢查老年代最大可用的連續(xù)空間是否大于歷次晉升到老年代對(duì)象的平均大小,如果大于,將嘗試著進(jìn)行一次 Minor GC;如果小于,或者 HandlePromotionFailure 的值不允許冒險(xiǎn),那么就要進(jìn)行一次 Full GC。
對(duì)于 Minor GC,其觸發(fā)條件非常簡(jiǎn)單,當(dāng) Eden 空間滿(mǎn)時(shí),就將觸發(fā)一次 Minor GC。而 Full GC 則相對(duì)復(fù)雜,有以下條件:
1. 調(diào)用 System.gc()
只是建議虛擬機(jī)執(zhí)行 Full GC,但是虛擬機(jī)不一定真正去執(zhí)行。不建議使用這種方式,而是讓虛擬機(jī)管理內(nèi)存。
2. 老年代空間不足
老年代空間不足的常見(jiàn)場(chǎng)景為前文所講的大對(duì)象直接進(jìn)入老年代、長(zhǎng)期存活的對(duì)象進(jìn)入老年代等。
為了避免以上原因引起的 Full GC,應(yīng)當(dāng)盡量不要?jiǎng)?chuàng)建過(guò)大的對(duì)象以及數(shù)組。除此之外,可以通過(guò) -Xmn 虛擬機(jī)參數(shù)調(diào)大新生代的大小,讓對(duì)象盡量在新生代被回收掉,不進(jìn)入老年代。還可以通過(guò) -XX:MaxTenuringThreshold 調(diào)大對(duì)象進(jìn)入老年代的年齡,讓對(duì)象在新生代多存活一段時(shí)間。
3. 空間分配擔(dān)保失敗
使用復(fù)制算法的 Minor GC 需要老年代的內(nèi)存空間作擔(dān)保,如果擔(dān)保失敗會(huì)執(zhí)行一次 Full GC。具體內(nèi)容請(qǐng)參考上面的第 5 小節(jié)。
4. JDK 1.7 及以前的永久代空間不足
在 JDK 1.7 及以前,HotSpot 虛擬機(jī)中的方法區(qū)是用永久代實(shí)現(xiàn)的,永久代中存放的為一些 Class 的信息、常量、靜態(tài)變量等數(shù)據(jù)。
當(dāng)系統(tǒng)中要加載的類(lèi)、反射的類(lèi)和調(diào)用的方法較多時(shí),永久代可能會(huì)被占滿(mǎn),在未配置為采用 CMS GC 的情況下也會(huì)執(zhí)行 Full GC。如果經(jīng)過(guò) Full GC 仍然回收不了,那么虛擬機(jī)會(huì)拋出 java.lang.OutOfMemoryError。
為避免以上原因引起的 Full GC,可采用的方法為增大永久代空間或轉(zhuǎn)為使用 CMS GC。
5. Concurrent Mode Failure
執(zhí)行 CMS GC 的過(guò)程中同時(shí)有對(duì)象要放入老年代,而此時(shí)老年代空間不足(可能是 GC 過(guò)程中浮動(dòng)垃圾過(guò)多導(dǎo)致暫時(shí)性的空間不足),便會(huì)報(bào) Concurrent Mode Failure 錯(cuò)誤,并觸發(fā) Full GC。
免責(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)容。