GC垃圾回收演算法總結
阿新 • • 發佈:2018-12-24
閒著沒事總結下java虛擬機器的垃圾回收演算法。
哪些物件會被回收
兩種方式:
- 第一種:引用計數法:只要一個物件被引用,計數就+1,釋放引用,就-1,但是無法解決兩個物件互相引用的問題
第二種:物件可達狀態分析
主要包括:- 虛擬機器棧中引用的物件。
- 方法區中類靜態屬性實體引用的物件。
- 方法區中常量引用的物件。大多數是final修飾的
- 本地方法棧中JNI引用的物件。
回收理論演算法
- 複製演算法:將堆記憶體分成兩個區域,當一個區域的一小塊記憶體使用完後,清理未被引用的物件,將剩下的存活的物件複製到另一塊記憶體中,然後清除前一塊記憶體,這樣複製效率低下
- 標記-清除演算法:對堆記憶體中的物件進行遍歷,找到未被引用的物件,然後清除,但是這樣會產生大量碎片化記憶體,浪費記憶體,降低記憶體使用率。
- 標記-壓縮演算法:這個主要針對老年代的物件,因為老年代的物件存活率很高,所以需要在一定時間對存活率物件進行壓縮至記憶體一側,然後清除記憶體壓縮邊界以外的記憶體,這樣可以減少記憶體備份,很好利用記憶體空間。
- 分代演算法:堆記憶體主要分為新生代和老年代,新生代物件大多是新建一次的存活率很低的物件,直接使用複製演算法,老年代演算法可以使用標記壓縮演算法
回收工具
- Seril收集器:新生代序列,老年代序列,單執行緒
- ParNew收集器:多執行緒,新生代並行,老年代序列
- Parallel收集器:更加關注於系統的吞吐量,新生代複製演算法+老年代標記壓縮演算法
- Parallel old收集器,這是jdk1.6以後才有,主要是由新生代parrallel收集器+老年代並行
- CMS,current mark sweep,原則是以最短回收停頓時間為主的收集器,其主要是以標記-清除演算法來實現的,基本步驟如下:
初始標記(CMS initial mark)
併發標記(CMS concurrent mark)
重新標記(CMS remark)
併發清除(CMS concurrent sweep)
其中初始標記是快速標記gc roots能夠關聯的物件,併發標記主要是GC Roots Tracing的過程,重新標記是併發期間,標記使用者從新操作新產生或者變化的物件,稍微比初始標記慢一點,但是比並發標記快很多,併發清除是指清除gc物件。
由於併發標記和併發清除是最耗時的階段,收集器可以和使用者併發工作的,主要是老年代收集器。 - G1收集器,這個不太清楚,見以下連結