1. 程式人生 > >GC垃圾回收演算法總結

GC垃圾回收演算法總結

閒著沒事總結下java虛擬機器的垃圾回收演算法。

哪些物件會被回收

兩種方式:

  • 第一種:引用計數法:只要一個物件被引用,計數就+1,釋放引用,就-1,但是無法解決兩個物件互相引用的問題
  • 第二種:物件可達狀態分析
    主要包括:

    1. 虛擬機器棧中引用的物件。
    2. 方法區中類靜態屬性實體引用的物件。
    3. 方法區中常量引用的物件。大多數是final修飾的
    4. 本地方法棧中JNI引用的物件。

回收理論演算法

  1. 複製演算法:將堆記憶體分成兩個區域,當一個區域的一小塊記憶體使用完後,清理未被引用的物件,將剩下的存活的物件複製到另一塊記憶體中,然後清除前一塊記憶體,這樣複製效率低下
  2. 標記-清除演算法:對堆記憶體中的物件進行遍歷,找到未被引用的物件,然後清除,但是這樣會產生大量碎片化記憶體,浪費記憶體,降低記憶體使用率。
  3. 標記-壓縮演算法:這個主要針對老年代的物件,因為老年代的物件存活率很高,所以需要在一定時間對存活率物件進行壓縮至記憶體一側,然後清除記憶體壓縮邊界以外的記憶體,這樣可以減少記憶體備份,很好利用記憶體空間。
  4. 分代演算法:堆記憶體主要分為新生代和老年代,新生代物件大多是新建一次的存活率很低的物件,直接使用複製演算法,老年代演算法可以使用標記壓縮演算法

回收工具

  1. Seril收集器:新生代序列,老年代序列,單執行緒
  2. ParNew收集器:多執行緒,新生代並行,老年代序列
  3. Parallel收集器:更加關注於系統的吞吐量,新生代複製演算法+老年代標記壓縮演算法
  4. Parallel old收集器,這是jdk1.6以後才有,主要是由新生代parrallel收集器+老年代並行
  5. CMS,current mark sweep,原則是以最短回收停頓時間為主的收集器,其主要是以標記-清除演算法來實現的,基本步驟如下:
    初始標記(CMS initial mark)
    併發標記(CMS concurrent mark)
    重新標記(CMS remark)
    併發清除(CMS concurrent sweep)
    其中初始標記是快速標記gc roots能夠關聯的物件,併發標記主要是GC Roots Tracing的過程,重新標記是併發期間,標記使用者從新操作新產生或者變化的物件,稍微比初始標記慢一點,但是比並發標記快很多,併發清除是指清除gc物件。
    由於併發標記和併發清除是最耗時的階段,收集器可以和使用者併發工作的,主要是老年代收集器。
  6. G1收集器,這個不太清楚,見以下連結