【深入理解Java虛擬機器】垃圾回收

monkjavaer發表於2021-03-06

引用計數演算法

給物件加一個計數器,引用一次+1,引用時效就-1,當計數器=0時物件就不能再被使用;
實現簡單,判定效率高;Java虛擬接沒有使用,主要原因是很難解決物件之間迴圈引用問題;

GC演算法:

GC Roots 作為起始點,開始向下搜尋,這個搜尋路徑叫做引用鏈,當一個物件到GC Roots沒有任何引用鏈,那麼這個物件就是不可用的。
Java中可作為GC Roots的物件:虛擬機器棧中的引用物件、方法區中類靜態屬性引用物件、方法區中常量引用物件等。

標記清除演算法

分為標記和清除階段,首先標記所有需要回收的物件,在標記完後統一回收標記的物件。
堆中的老年代:因為存活率高,沒有額外空間進行分配擔保,就必須使用標記清理演算法回收。
標記清理演算法問題:

  • 1、標記和清除的效率不高;
  • 2、標記清除後會產生大量不連續的記憶體碎片,當需要分配較大物件時無法找到足夠記憶體,又會觸發垃圾收集動作;

複製演算法

堆中的新生代:每次垃圾回收都有大量物件死去,只有少量存活所以使用複製演算法;
jvm的複製演算法是將記憶體劃分為一塊較大空間Eden和兩塊較小的Suvivor,一般比例是8:1:1。每次只是用Eden和Suvivor中的一塊,當回收時,將Eden和Suvivor中存活的物件複製到另一塊Suvivor中,再將Eden和使用的Suvivor清除掉。

標記壓縮演算法(標記整理)

標記-壓縮演算法與標記-清理演算法類似,只是後續步驟是讓所有存活的物件移動到一端,然後直接清除掉端邊界以外的記憶體

垃圾收集器

常見的垃圾收集器:

Serial:新生代收集器,單執行緒。
ParNew:新生代收集器,Serial的多執行緒版本,和CMS配合工作。
Parallel Scavenge:新生代,可以控制吞吐量。配合自適應調節策略,可以讓虛擬機器自動完成記憶體調優。
Serial Old:Serial老年代版本,單執行緒。
Parallel Old:Parallel Scavenge老年代版本,多執行緒
CMS:老年代收集器,特點:併發,低停頓,以獲取最短回收停頓時間為目標。基於標記-清除演算法。
CMS過程

  • 1初始標記 :標記GC Roots能直接關聯的物件,速度很快。
  • 2併發標記 :進行GC Roots Tracing的過程,耗時長
  • 3 重新標記 :修正併發標記期間不正確的標記記錄
  • 4 併發清除

Minor GC和Full GC之間的區別

堆記憶體劃分為 Eden、和兩塊Survivor,JDK1.8移除了永久代。

  • Minor GC 新生代GC: JAVA物件大多具備朝生夕滅的特性,所以Minor GC非常頻繁,回收速度也比較快。
  • Full GC/Major GC 老年代GC: 速度一般比Minor GC慢很多。

記憶體分配策略

  • 物件優先在新生代Eden區中分配,當Eden區沒有足夠空間時,虛擬機器發起Minor GC.
  • 大物件直接進入老年代,大物件典型的就是很長的字串或陣列。
  • 長期存活的物件進入老年代。

相關文章