JVM——內存分配與回收策略

1、對象優先在Eden區分配

大多數情況下,對象在新生代Eden區分配。當Eden區沒有足夠的空間進行分配時,虛擬機將發起一次Minor GC

虛擬機提供了 -XX+PrintGCDetails這個收集器參數,告訴虛擬機在發生垃圾回收時打印內存回收日誌。並且在進程退出時輸出當前的內存各區域分配情況。

 

2、大對象直接進入老年代

  所謂的大對象是指需要大量連續內存空間的Java對象。大對象對虛擬機的內存分配來說是一個壞消息,經常出現大對象導致內存還有不少空間時就提前觸發垃圾回收以獲得足夠的連續空間來“安置”大對象。

虛擬機提供了一個-XXpretenureSizeThreshold參數,令大於這個設置值的對象直接在老年代分配,這樣做的目的是避免在Eden及兩個Survivor區域間發生大量的內存複製。

 

3、長期存活的對象將直接進入老年代

虛擬機採用分代收集的思想管理內存,則內存回收即必須識別哪些對象應該放在老年代,哪些對象應該放在新生代。爲了做到此,虛擬機給每個對象設置了年齡計數器(Age)。

如果對象在Eden區域出生並且經過一次Minor GC後依然存活,並且被Survivor區域容納話沒,被移至Survivor區域,年齡+1。對象在Survivor區域每“熬過”一次Minor GC,年齡就+1,當其年齡增加到一定程度(默認15),就會晉升至老年代。

對象晉升老年代的年齡閾值,可以通過-XX:MaxTenuringThreshold參數設置。

4、動態對象年齡判定

爲了更好的適應不同程序的內存狀況,虛擬機並不是永遠的要求對象的年齡必須達到MaxTenuringThreshold才能晉升老年代,如果在Survivor空間中相同年齡所有對象大小總和大於Survivor空間的一半,年齡大於或等於該年齡的對象可以直接進入老年代,無需等到MaxTenuringThreshold中要求的年齡。

5、空間分配擔保

在發生Minor GC之前,虛擬機會先檢查老年代的最大可用的連續空間是否大於新生代所有對象的總空間,如果條件成立,那麼Minor GC可以確保是安全的。如果不成立,則虛擬機會查看HandlePromotionFailure設置的值是否允許擔保失敗。如果允許,那麼會繼續檢查老年代最大可用的連續空間是否大於歷次晉升老年代對象的平均大小,如果大於,將嘗試進行一次Minor GC,儘管這次Minor GC是有風險的;如果小於,或者HandlePromotionFailure設置不允許冒險,那麼這時要改爲進行一次Full GC


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章