1. 程式人生 > >JVM內存分配與回收策略

JVM內存分配與回收策略

failure ret 虛擬機 收集器 字符 設置 足夠 java 選擇

對象優先在Eden分配

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

Minor GC:新生代GC,指發生在新生代的垃圾收集動作,因為Java對象大多具備朝生夕滅的特性,所以Minor GC非常頻繁,一般回收速度也比較快。
Major GC/Full GC:老年代GC,指發生在老年代的GC,出現了Major GC,經常會伴隨至少一次Minor GC(但非絕對的,在Parallel Scavenge收集器的收集策略中就有直接進行Major GC的策略選擇過程)。Major GC的速度一般比Minor GC慢10倍以上。

大對象直接進入老年代

  • 大對象:需要大量連續內存空間的Java對象,最典型的大對象就是很長的字符串以及數組。
  • -XX:PretenureSizeThreshold參數可以設置,令大於這個設置值的對象直接在老年代分配,只對Serial和ParNew收集器有用。

長期存活的對象將進入老年期

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

動態對象年齡判斷

  • 如果Survivor空間中相同年齡所有對象大小的總和大於Survivor空間的一半,年齡大於或等於該年齡的對象就可以直接進入老年代,而不需要等到MaxTenuringThreshold中要求的年齡。

空間分配擔保

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

JVM內存分配與回收策略