天天看點

垃圾回收GC概要

概要

  1. 哪裡需要收集:java堆和方法區(廢棄常量和無用的類)

    無用的類:

    該類所有的執行個體都已經被回收,堆中不存在該類的任何執行個體

    加載該類的ClassLoader被回收

    該類對應的java.lang.class對象沒有在任何地方被引用,無法再任何地方通過反射通路該類的方法

  2. 什麼時候回收:對象已經死亡

    可達性分析算法:通過一系列的“GC Roots”的對象作為起始點,從這些節點開始向下搜尋,搜尋所走過的路徑稱為引用鍊(Reference Chain),當一個對象到GC Roots沒有任何引用鍊相連時,此對象是不可用的

    可作為GC Roots的對象:

  3. 虛拟機棧中引用的對象
  4. 方法去中類靜态屬性引用的對象
  5. 方法去中常量引用的對象

    真正的宣告死亡需要兩次标記過程

    如果可達性分析算法已經判定死亡,将會進行第二次的篩選,是否有必要執行finalize()方法

    垃圾回收算法

  6. 标記-清除:首先标記出所有需要回收的對象,在标記完成後統一回收所有被标記的對象
  7. 不足:1效率不高2空間問題:産生碎片
  8. 複制算法:将可用記憶體劃分為大小相等的兩塊,每次隻使用其中一塊,當用完了,将存在活着的複制到另外一塊,然後将使用過的空間一次性清理掉。
  9. 标記-整理:标記完成之後,将所有存活的對象都想一端移動,直接清理掉邊界以外的記憶體。
  10. 分代收集:java堆分為新生代和老年代

    例子:HotSpot實作

    使用OopMap 的資料結構,在類加載完成的時候,吧對象内 什麼偏移量上是什麼類型的資料計算出來,在JIT編譯過程中,也會在特定的位置記錄下棧和寄存器中哪些位置的引用

    程式執行時并非在所有地方都能停頓下來開始GC,隻有達到安全點時才能暫停

    垃圾回收GC概要

    垃圾收集器總結

分類 所屬分代 使用線程 使用算法
Serial 新生代 單線程 複制(新)、标記-整理(老)
ParNew 新生代 多線程 複制(新)、标記-整理(老)
Parallel Scavenge 新生代 多線程 吞吐量優先算法
Serial Old 老生代 單線程 複制(新)、标記-整理(老)
Parallel Old 老生代 多線程 複制(新)、标記-整理(老)
CMS 老生代 多線程 标記-清除算法(初始标記、并發标記、重新标記、并發清除)
G1 新生代&&老生代 多線程 标記-整理算法(初始标記、并發标記、最終标記、篩選回收)