內存分配與回收策略

內存分配與回收策略

    1.對象優先在Eden分配

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

        -XX:+PrintGCDetails:在發生垃圾收集行爲時打印內存回收日誌,並且在進程退出的時候輸出當前的內存各區域分配情況。

        -XX:SurvivorRatio=8決定了新生代中Eden區與一個Survivor區的空間比例是8:1。

        新生代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倍以上。

    

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

        大對象:需要大量連續內存空間的Java對象,

        -XX:PretenureSizeThreshold:令大於這個設置值的對象直接在老年代分配。目的是避免在Eden區及兩個Survivor區直接發生大量的內存複製(新生代採用複製算法收集內存)。該參數只對Serial和ParNew兩款收集器有效。

    

    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。

        新生代使用複製收集算法,爲了內存利用率,只是用其中一個Survivor空間來作爲輪換備份,因此當出現大量對象在Minor GC後仍然存活的情況,就需要蘭年度進行分配擔保,吧Survivor無法容納的對象直接進入老年代。老年代要進行這樣的擔保,前提是老年代本身還有容納這些對象的剩餘空間。

        JDK1.6之後的規則變爲只要老年代的連續空間大於新生代對象總大小或者歷次晉升的平均大小就會進行Minor GC,否則將進行Full GC。HandlePromotionFailure參數不會再影響到虛擬機的空間分配擔保策略。


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