5.JVM垃圾收集算法

概述

本文主要是介紹幾種垃圾收集算法的基本思路,包括標記-清除算法、複製算法、標記整理算法、分代收集java

標記-清除算法

基本思路

分爲「標記」和「清除」兩個步驟,先標記全部須要回收的對象,再統一進行清除被標記的對象。
標記-清除算法(摘自《深刻理解Java虛擬機》).png算法

評價

  • 效率低,不管是標記過程仍是清除過程。
  • 標記後直接清除,沒有對內存空間進行整理,會產生大量不連續的內存碎片。當程序運行須要分配較大對象時,會因爲沒有足夠的連續內存而提早觸發一次GC。

複製算法

基本思路

將內存分爲兩塊大小相等的區域,每次只使用其中的一塊來分配內存,當其中一塊內存空間用完了,觸發GC時,將仍然存活的對象複製到另外一塊內存上,再將使用過的內存一次性清理掉。
複製算法(摘自《深刻理解Java虛擬機》).pngspa

實際使用

如今的商業虛擬機都採用複製算法來回收新生代,因爲新生代的對象存活率很低,因此將內存空間劃分爲Eden區和兩個Survivor區,每次分配內存都在Eden區和其中一個Survivor區進行。當發生垃圾回收時,將Eden和Survivor區中存活的對象複製到另外一個Survivor區,而後直接清空剛纔兩個區。
hotspot虛擬機提供的Eden和Survivor空間的默認比例爲8:1,即最多隻會浪費10%的內存空間。通常來講,新生代對象死亡率達到98%,可是不能保證特殊狀況。因此,若是另一塊Survivor空間沒有足夠空間存放上一次新生代收集下來的存活對象時,對象將經過分配擔保機制進入老年代。對象

評價

  • 複製算法不會產生內存碎片,保證內存空間規整。
  • 若是使用兩塊大小相等的內存區域來作複製算法,內存的資源利用率過小,代價太大。商業虛擬機的內存劃分將內存利用率提高至90%,解決了內存使用率的問題。
  • 當對象存活率高時,複製操做的過程就會變得很頻繁,效率較低。而且因爲須要劃份內存,因此須要額外的空間來作分配擔保,防止空間不足的極端狀況。因此複製算法適用新生代垃圾回收,而不適用於老年代。

標記-整理算法

基本思路

標記過程與「標記-清除」算法相同,而後讓全部的存活對象朝着一端進行移動,以後直接將存活對象以外的內存空間進行清理。
標記-整理算法(摘自《深刻理解Java虛擬機》).pngblog

評價

  • 當對象過多時,標記和整理兩個過程效率低
  • 不產生內存碎片,保證內存空間規整,方便分配內存
  • 適用於老年代垃圾回收

分代收集算法

分代收集算法不算一種回收算法,相似於多種算法的綜合使用。分代收集算法的思路主要是:按照對象存活時間,將內存劃分爲不一樣的區域,通常來講,將java堆劃分爲新生代和老年代,這樣能夠根據不一樣區域的對象的特色來採用最適當的收集算法。例如新生代對象死亡率高,則採用複製算法;老年代對象存活率高,而且沒有多餘內存空間作分配擔保,則採用「標記-清除」或「標記-整理」進行算法收集。內存

相關文章
相關標籤/搜索