JVM垃圾回收的過程

JVM垃圾回收的算法不少,可是無論是哪一種算法,在進行GC時大體的流程都是差很少的,主要有如下3個過程:算法

1. 枚舉根節點

這個過程主要是找到全部的GC Roots對象,這些對象通常發生在JVM虛擬機棧棧幀、常量池中的靜態對象、方法區中靜態類屬性引用、本地方法棧中引用的對象。這個過程會發生STW,全部的線程均運行到安全區域(Safe Region)纔開始執行。安全

一般有兩種算法:
  • 引用計數法:每一個對象中添加一個引用計數器,每當有一個地方引用它時,計數器值就+1;當引用失效時,計數器值就-1;任什麼時候刻計數器爲0的對象就是不可能在被使用的。

優勢是效率高,缺點是循環引用沒法處理,致使內存溢出併發

  • 可達性分析:以GC Roots爲根節點,從這些根節點開始向下搜索,搜索所走過的路徑稱爲引用鏈(Reference Chain),當一個對象不在任何引用鏈相連時,則證實此對象是不可用的。

優勢能夠檢測全部的對象,缺點效率低spa

GC Roots節點通常爲:
  • 虛擬機棧中棧幀引用的對象
  • 本地方法棧JNI中棧幀引用的對象
  • 常量池中引用的對象
  • 類中的靜態變量應用的對象

2. 標記

標記的過程主要是標記哪些對象是須要被回收的,有的GC算法是並行的,有的是和GC Roots標記一塊兒執行。若是是並行的,不會發生STW。線程

若是是併發標記的GC算法,後面還有有一次從新標記或者最終標記。這主要是來解決在併發標記的過程當中,用戶線程還在一直執行,這期間有變化的對象。code

標記算法常見的有兩種:
  • 標記–清除算法或者標記–整理算法:爲每一個對象存儲一個標記位,記錄對象的狀態(活着或是死亡)對象

  • 複製算法:將內存平均分紅兩部分,而後每次只使用其中的一部分,當這部份內存滿的時候,將內存中全部存活的對象複製到另外一個內存中,而後將以前的內存中死亡的對象清空。排序

3. 清除或回收

這個階段會根據GC算法的不一樣採起不一樣的回收策略。內存

  • CMS算法在回收的時候會考慮停頓時間,儘可能減小GC線程佔用的時間
  • G1算法先對各個Region的回收價值和成本進行排序,根據用戶所指望的GC停頓時間來制定回收計劃
  • 標記-清除算法在第二階段(清除階段)將對象回收
  • 複製算法是經過將存活對象複製到另外一塊內存區域,將當前區域中未被複制的對象進行清除
相關文章
相關標籤/搜索