【Java JVM】Java虛擬機器記憶體分配幾個原則
1、大多數情況下,物件在新生代Eden區中分配。當Eden區沒有足夠空間進行分配時,虛擬機器將發起一次Minor GC
2、大物件直接進入老年代。大物件指需要大量連續記憶體空間的Java物件,最典型的大物件就是那種很長的字串以及陣列。
3、長期存活的物件將進入老年代。
虛擬機器採用分代收集的思想來管理記憶體,那麼記憶體回收時就必須能識別哪些物件應放在新生代,哪些物件應放在老年代中。為了做到這一點,虛擬機器給那個物件定義了一個物件年齡計數器。如果物件在Eden出生並經過第一次Minor GC後仍然存活,並且能背Survivor容納的話,將被移動到Survivor空間中,並且物件年齡設為1。物件在Survivor區中每熬過一次Minor GC,年齡就增加1歲,當他的年齡增加到一定程度(預設為15歲),就將會被晉升到老年代中。物件晉升老年代的年齡閾值,可以通過引數 -XX:MaxTenuringThreshold設定。4、動態物件年齡判定。為了能更好地適應不同程式的記憶體狀況,虛擬機器並不是永遠的要求物件的年齡必須達到了MaxTenuringThreshold才能晉升到老年代,如果在Survivor空間中相同年齡所有物件大小總和大雨Survivor空間的一半,年齡大於或等於該年齡的物件就可以直接進入老年代。
5、空間分配擔保。
在發生Minor GC之前,虛擬機器會先檢查老年代最大可用的連續空間是否大於新生代所有物件總空間,如果這個條件成立,那麼Minor GC可以確保是安全的。如果不成立,則虛擬機器會檢視HandlePromotionFailure設定值是否允許擔保失敗。如果允許,那麼會繼續檢查老年代最大可用的連續空間是否大於歷次晉升到老年代物件的平均大小,如果大於,將嘗試著進行一次Minor GC,儘管這次Minor GC是有風險的;如果小於或者HandlePromotionFailuer設定不允許冒險,那這時也要改為進行一次Full GC。