[總結]-第三章 垃圾收集器與內存分配策略

[總結]-第三章 垃圾收集器與內存分配策略

1、知識點

一、對象是否存活的斷定

  • 引用計數法
  • 可達性分析(GC Roots)

斷定對象死亡須要通過2次標記:java

  • 第一次標記:可達性分析後沒有與GC Roots相鏈接的引用鏈。
  • 第二次標記:GC對F-Queue中的對象進行標記(低優先級的Finalizer線程會去執行F-Queue中對象的finalize()方法)

二、引用分類

  • 強引用(Strong Reference)
    • 主要強引用還在,則垃圾收集器不會回收被引用的對象。
  • 軟引用(Soft Reference)
    • 內存不足即將OOM時,回收。好比:緩存數據。
  • 弱引用(Weak Reference)
    • 只要gc就回收。
  • 虛引用(Phantom Reference)
    • 能夠判斷被關聯的對象是否被GC

三、finalize( )

  • 任何一個對象的finalize()方法都只會被系統自動調用一次。(注意是對象,並非類);
  • finalize()若是耗時過長,GC並不會等待。它只是通知另外一個線程(Finalizer)去執行而已;
  • 知道便可,不建議使用;

四、垃圾收集算法

  • 引用計數器
    • 優勢:實時性,只要對象的引用計數器爲0,馬上回收;
    • 缺點:互相引用就永遠沒法去除。
  • 標記、清除(通常在老年代適用)
    • 標記:找到全部可訪問的對象,作個標記;
    • 清除:遍歷堆,把未標記的對象清除;
    • 缺點:一、標記、清除效率都低;二、空間內存碎片;三、STW;
  • 標記、整理(通常在老年代適用)
    • 標記:找到全部可訪問的對象,作個標記;
    • 整理:將存活對象向一端移動,最後清除端邊界之外的對象;
  • 複製(通常在新生代適用)
    • 優勢:GC時,將存活的對象複製到另一半空間中,刪除當前空間全部遺留對象便可。簡單高效。
    • 缺點:須要浪費一半空間。
    • 衍生:Eden(1)+ Survivor(2),默認 Eden:Survivor:Survivor = 8:1:1。
  • 分代收集
    • 新生代使用複製算法;
    • 年老代使用標記清除或標記整理算法。

五、安全點和安全區域

  • 安全點:以「是否具備讓程序長時間執行的特徵」來選定。好比方法調用、循環跳轉、異常跳轉等。程序運行到安全點後會停下來進行GC;算法

  • 安全區域:線程進入SafeRegion,若是此時JVM發起GC,則無論進入安全區域的線程。在線程離開安全區域以前,檢查系統是否已經完成了根節點枚舉或整個GC過程。如完成,則線程繼續執行,若是沒完成,則必須等待。緩存

六、垃圾收集器

  • CMS(Concurrent Mark Sweep)安全

    • 定義:
      • 以獲取最短回收停頓爲目標的收集器;
      • 基於「標記-清除」算法。
    • 步驟:
      • 初始標記(STW):標記GC Roots能關聯的對象,速度很快。
      • 併發標記:進行GC Roots Tracing(追蹤)的過程,耗時較長。好在能夠併發。
      • 從新標記(STW):修正併發標記期間,產生變更的那一部分對象的標記記錄。
      • 併發清除:耗時較長。好在能夠併發。
    • 優勢:
      • 併發收集、低停頓。
    • 缺點:
      • CMS收集器對CPU資源很是敏感:CMS默認啓動的回收線程數是(CPU數量+3)/4。
      • CMS收集器沒法處理浮動垃圾:須要等待下一次GC時再清理。
      • 基於「標記清除」算法,會有大量空間碎片
  • G1(Garbage-First)微信

    • 定義:
      • 將整個java堆劃成多個大小相等的獨立區域(Region);
      • 經過維護一個優先列表,來有計劃的回收價值最大的Region;
      • G1中每一個Region都有 一個與之對應的Remembered Set,存儲使用此對象的引用信息。
    • 步驟:
      • 初始標記
      • 併發標記
      • 最終標記:修正在併發標記期間,產生變更的那一部分標記記錄。虛擬機會將變化計入Remembered Set Logs中(併發標記期間)。最終標記須要將Remembered Set Logs 合併到Remembered Set中。
      • 篩選回收:對各個Region的回收價值和成本進行排序,根據用戶指望的GC停頓時間來制定計劃後開始GC。
    • 優勢:
      • 並行與併發
      • 分代收集
      • 空間整合:基於標記整理或複製算法,不會有空間碎片。
      • 可預測的停頓
    • 缺點:
      • 若是應用追求吞吐量,則G1並無什麼特別的好處。

七、新生代GC與老年代GC

  • 新生代GC(MinorGC):指發生在新生代的垃圾收集動做,由於Java對象大多都具有朝生夕滅的特性,因此MinorGC特別頻繁,通常回收速度也比較快。併發

    • 當Eden區內存不足時,觸發MinorGC。
    • 歷次晉升的平均大小 < 老年代的連續空間,觸發MinorGC。
  • 老年代GC(MajorGC/FullGC):指發生在老年代的GC,出現了MajorGC,常常會伴隨至少一次的MinorGC。速度通常會比MinorGC慢10倍以上。.net

    • 歷次晉升的平均大小 > 老年代的連續空間,觸發FullGC。

只要老年代的連續空間大於新生代對象總大小或者歷次晉升的平均大小就會進行MinorGC,不然將進行FullGC。線程

八、進入老年代

  • 大對象直接進入老年代對象

    • -XX:PretenureSizeThreshold參數,比此值大的會直接在老年代分配。
    • 目的是避免在Eden區及兩個Survivor區之間發生大量的內存複製。
  • 長期存活的對象進入老年代排序

    • -XX:MaxTenuringThreshold默認15,每次MinorGC後,年齡+1。
  • 動態對象年齡

    • 若是在Survivor空間中相同年齡全部對象大小的總和大於Survivor空間的一半,年齡大於或等於該年齡的對象就直接進入老年代。

博客

https://my.oschina.net/gmarshal

歡迎關注個人我的微信訂閱號:(聽說這個頭像程序猿專用)

輸入圖片說明

相關文章
相關標籤/搜索