深入理解Java虛擬機(4)內存分配與回收策略

一、對象優先在Eden分配

 大多數情況下,對現在新生代Eden區中分配,當Eden區沒有足夠空間時,虛擬機將發起一次Minor GC。
 新生代GC(Minor GC):指發生在新生代的垃圾收集動作,因爲大多Java對象壽命短暫,所以Minor GC非常頻繁,回收速度快。
 老年代GC(Major GC/Full GC):指發生在老年代的GC,出現了Major GC,經常伴隨着至少一次的Minor GC(但並非絕對的,在Parallel Scavenge收集器的收集策略裏就有直接進行Major GC的策略選擇過程),Major GC的速度一般會比Minor GC慢10倍以上。

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

  大對象是指:需要大量連續內存空間的Java對象,最典型的大對象就是那種很長的字符串以及數組。虛擬機提供了一個-XX: PretenureSizeThreshold參數,令大於這個設置值的對象直接進入老年代,這樣避免了大對象在Eden區以及兩個Survivor之間發生大量的內存複製(複習:新生代採用複製算法收集內存)。
  注:PretenureSizeThreshold參數只對Serial和PreNew兩款收集器有效,Parallel Scavenge收集器不認識這個參數,
  Parallel Scavenge收集器一般不需要設置,如果用到必須要使用此參數的場合,可以考慮ParNew+CMS收集器組合。

三、長期存活的對象進入老年代

  虛擬機給每個對象定義了一個對象年齡(Age)計數器,如果對象在Eden出生並經過第一次Minor GC後仍然存活,並且能被Survivor容納的話,將被移動到Survivor空間中,並且年齡設爲1.對象在Survivor中每熬過一次Minor GC,年齡就增加一歲,當年齡增加到一定程度(默認15歲),將會被晉升到老年代。年齡閾值可以通過參數-XX:MaxTenuringThreshold設置。

四、動態對象年齡判定

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

五、空間分配擔保

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

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