Java對象歷險記 [動圖]

對象的分配和回收流程

如上圖動畫所示:html

一、優先在Eden區分配對象

  • Eden區空間不足,觸發Minor GC,標記可回收對象,而後Eden區存活對象拷貝到往Survivor-From區,接下來清空Eden區;
  • 再次觸發Minor GC,掃描Eden區和from區,把存活的對象複製到To區,清空Eden區和from區;
  • 若是在Minor GC複製存活對象到Survivor區時,發現Survivor區內存不夠,則提早把對象放入老年代;

二、大對象直接進入老年代

若是發現須要大量連續內存空間的Java對象,如很長的字符串或者數組,則直接把對象放入老年代。java

可經過-XX:PretenureSizeThreshold參數設置大對象的最小大小,該參數只對Serial和ParNew兩款收集器有效。算法

  • 由於新生代採用複製算法收集垃圾,大對象直接進入老年代,避免在Eden區和Survivor區發生大量內存複製;
  • 寫程序的時候儘可能避免大對象。

三、長期存活對象進入老年代

**固定對象年齡判斷:**默認的,存活對象在Survivor的From和To區來回交換15次後,若是對象最終仍是存活,就放入老年代。能夠經過-XX:MaxTenuringThreshold參數來設置對象的年齡。數組

**動態對象年齡判斷:**若是發現Survivor中有相同年齡的對象空間總和大於Survivor空間的一半,那麼年齡大於或者等於該年齡的對象直接晉升到老年代。架構

四、空間分配擔保

爲何須要分配擔保:若是Survivor區存活了不少對象,空間不夠了,都須要晉升到老年代,那麼久須要老年代進行分配擔保,也就是將Survivor沒法容納的對象直接進入老年代。jvm

  • 發生Minor GC前,JVM先檢查老年代最大可用連續空間是否大於新生代全部對象的總空間
    • 大於:空間足夠,直接Minor GC;
    • 小於:進行一次Full GC。

JDK 6 Update 24前會根據HandlePromotionFailure參數判斷是否容許擔保失敗,若是容許,則嘗試一次Minor GC;不然,則進行Full GC。動畫


本文做者: arthinkingcode

本文連接: www.itzhai.com/jvm/java-ob…cdn

Java對象歷險記 | 分配擔保,空間分配htm

版權聲明: 本博客全部文章除特別聲明外,均採用 BY-NC-SA 許可協議。轉載請註明出處!


更多垃圾回收機制,垃圾回收算法以及垃圾收集器相關文章,歡迎關注個人公衆號:Java架構雜談

相關文章
相關標籤/搜索