天天看點

JVM中GC什麼時候開始進行

  • 發生區域

    GC一般發生于堆空間中,堆空間主要分Eden和兩個survivor區。

  • 堆記憶體配置設定

    優先配置設定到Eden區中,當空間不足時發生Minor GC,大多數對象都是

    朝生夕滅,是以Minnor GC很頻繁,速度非常快。

  • Full GC

    發生在老年代,老年代沒有空間就會發生,發生之前會執行 一次Minnor GC。大的對象會直接進入老年代,虛拟機會提供一個PretenureSizeThreadhold參數,大于這個直接在老年代配置設定,避免在新生代來回複制。

  • Minnor GC

    發生時,會判斷需要晉升到老年代的大小老年代是否能存下,如果不能存下,則會發生Full GC。如果能存下的話,則檢視 HandlePromotionFailure 設定是否允許擔保失敗,如果允許,那隻會進行一次 Minor GC,如果不允許,則改為進行一次 Full GC。

資料顯示:

在JDK 6 Update 24之後,HandlePromotionFailure參數不會再影響到虛拟機的空間配置設定擔保政策,觀察OpenJDK中的源碼變化(見代碼清單),雖然源碼中還定義了HandlePromotionFailure參數,但是在代碼中已經不會再使用它。JDK 6 Update 24之後的規則變為隻要老年代的連續空間大于新生代對象總大小或者曆次晉升的平均大小就會進行Minor GC,否則将進行Full GC

bool TenuredGeneration::promotion_attempt_is_safe(size_t
max_promotion_in_bytes) const {
   // 老年代最大可用的連續空間
   size_t available = max_contiguous_available();  
   // 每次晉升到老年代的平均大小
   size_t av_promo  = (size_t)gc_stats()->avg_promoted()->padded_average();
   // 老年代可用空間是否大于平均晉升大小,或者老年代可用空間是否大于當此GC時新生代所有對象容量
   bool   res = (available >= av_promo) || (available >=
max_promotion_in_bytes);
  return res;
}