十、jvm垃圾回收演算法、垃圾收集器、引用你真的瞭解麼?

Hro發表於2018-12-04

一、垃圾回收演算法
  垃圾回收演算法分為垃圾收集演算法和垃圾回收演算法
  1、垃圾收集演算法:
   1)、引用計數器演算法: 有引用計數器+1,引用銷燬的時候,計數器-1,當引用計數器=0時, 物件已經沒有引用了,可以回收了!
   弊端:相互引用形成一個環,則無法回收。
   2)、根搜尋演算法(root節點演算法、可達性分析演算法) 從一個Root節點開始,尋找引用節點,剩餘沒有被引用的節點,則為無用節點,可以被回收。

  擴充套件:
   JAVA引用分類:
   a)、強引用: 建立一個物件並把這個物件賦給一個引用變數,有引用變數指向時永遠不會被垃圾回收; 例:Object obj = new Object(); obj物件對後面new Object的一個強引用
   b)、軟引用: 非必須引用,記憶體溢位之前進行回收;軟引用主要使用者實現類似快取的功能; 例:Object obj = new Object(); SoftReference sf = new SoftReference(obj); sf是對obj的一個軟引用
   c)、弱引用: 當JVM進行垃圾回收時,無論記憶體是否充足,都會回收被弱引用關聯的物件;
   d)、虛引用(幽靈/幻影引用): 每次垃圾回收的時候都會被回,主要用於檢測物件是否已經從記憶體中刪除。 每次垃圾回收的時候都會被回,主要用於檢測物件是否已經從記憶體中刪除。

2、垃圾回收演算法:
 1)、標記-清除演算法: 從根集合進行掃描,對存活的物件物件標記,標記完畢後,再掃描整個空間中未被標記的物件,進行回收
 缺點:由於直接回收不存活的物件,會造成記憶體碎片
 2)、複製演算法: 從根集合掃描,並將存活物件複製到一塊新的,沒有使用過的空間中
 缺點:需要一塊記憶體交換空間用於進行物件的移動,成本高。
 3)、標記-整理演算法: 採用標記-清除演算法一樣的方式進行物件的標記,但在清除時不同,在回收不存活的物件佔用的空間後, 會將所有的存活物件往左端空閒空間移動,並更新對應的指標;
 缺點:造成記憶體碎片,且成本更高
 4)、分代收集演算法: 根據物件存活的生命週期將記憶體劃分為若干個不同的區域,一般分為新生代(複製演算法)和老年代(標記整理演算法)

二、常見的垃圾收集器
 1、Serial收集器(複製演算法):單執行緒的收集器。在進行垃圾收集時,必須暫停其他所有的工作執行緒,直到收集完成。
 2、ParNew收集器:Serial收集器的多執行緒版本,在多核CPU環境下有著比Serial更好的表現。
 3、Parallel Scavenge(並行回收)收集器: 新生代收集器,它也是使用複製演算法的收集器,又是並行的多執行緒收集器。可達到一個可控制的吞吐量。 主要適合在後臺運算而不需要太多互動的任務。
 4、Serial Old 收集器:Serial收集器的老年代版本,它同樣是一個單執行緒收集器,使用標記整理演算法
 5、Parallel Old 收集器:是Parallel Scavenge收集器的老年代版本,使用多執行緒和“標記-整理”演算法
 6、CMS收集器:一種以獲取最短回收停頓時間為目標的收集器,
  步驟:初始標記(需要Stop The World,)、併發標記、重新標記(需要Stop The World,)、併發清除
  優點:併發收集,低停頓
  缺點:對CPU資源非常敏感;無法處理浮動垃圾;基於“標記-清除”演算法實現的收集器,會有大量空間碎片產生
 7、G1收集器:是一款面向服務端應用的垃圾收集器,
  步驟:初始標記、併發標記、最終標記、篩選回收
  優點:並行與併發,分代收集,空間整理 (標記整理演算法,複製演算法),可預測的停頓。

jdk1.7 預設垃圾收集器Parallel Scavenge(新生代)+Parallel Old(老年代)
jdk1.8 預設垃圾收集器Parallel Scavenge(新生代)+Parallel Old(老年代)
jdk1.9 預設垃圾收集器G1複製程式碼

相關文章