一,對象優(yōu)先在Eden分配
- 大多數(shù)情況下,對象在年輕代Eden區(qū)中分配,當Eden區(qū)沒有足夠空間進行分配時,虛擬機將發(fā)起一次Minor GC.
二,大對象直接進入老年代
- 所謂的大對象是指,需要大量連續(xù)內(nèi)存空間的java對象,最典型的大對象就是那種很長的字符串和數(shù)組
三,長期存活的對象將進入老年代
- 虛擬機采用了分代收集的思想來管理內(nèi)存,那么內(nèi)存回收時就必須能識別哪些對象放在新生代,哪些對象應(yīng)放在老年代中.為了能夠做到這一點,虛擬機給每個對象定義了一個對象年齡(age)計數(shù)器.如果對象在Eden出生并經(jīng)過第一次Minor GC后仍然存活,并且能被Survivor容納的話,將被移動到Survivor空間中,并且對象年齡設(shè)為1. 對象在Survivor中每"熬過"一次Minor GC,年齡就增加1歲. 當他的年齡增到一定程度(默認15歲),就將被提升到老年代中.
- 對象晉升到老年代的年齡閾值,可以通過-XX:MaxTenuringThreshold設(shè)置
四,動態(tài)對象年齡判斷
- 為了更好適應(yīng)不同程序的內(nèi)存狀況,虛擬機并不是永遠地要求對象的年齡必須達到了MaxTenuringThreshold才能晉升老年代,如果在Survivor空間中相同年齡所有對象大小的總和大于Survivor空間的一半,年齡大于或等于該年齡的對象就可以直接進入老年代,無需等到MaxTenuringThreshold中要求的年齡
五,空間分配擔保
- 在發(fā)生Minor GC之前,虛擬機會先檢查老年代最大可用的連續(xù)空間是否大于新生代所有對象總空間,如果這個條件成立,那么Minor GC可以確保是安全的. 如果不成立,則虛擬機會查看設(shè)置值是否允許擔保失敗.如果允許,那么會繼續(xù)檢查老年代最大可用的連續(xù)空間是否大于歷次晉升到老年代對象的平均大小,如果大于,將嘗試著進行一次Minor GC,盡管這次MinorGC是有風險的; 如果小于,或者HandlePromotionFail設(shè)置不允許冒險,那這時也要改為進行一次Full GC
- 取平均值進行比較其實仍然是一種動態(tài)概率的手段,也就是說,如果某次Minor GC存活的對象突增,遠遠高于平均水平的話,依然會導致?lián)J?HandlePromotionFail).如果出現(xiàn)了HandlePromotionFail失敗,那就只好在失敗后重新發(fā)起一次Full GC.
參考:
1,<<深入理解Java虛擬機 JVM高級特性與最佳實踐 第二版 周志明>>