天天看點

【深入了解JVM】垃圾收集算法

标記-清除算法

普通的标記-清除算法是最基礎的垃圾收集算法。分為“标記和收集兩個階段”

标記:标記出需要回收的對象,在标記完成後統一回收。标記靠的是前一文所講的判斷對象存活算法進行标記的。

清除:清除記憶體區域。

缺點:

  1. 效率低,标記和清除效率都不高。
  2. 空間問題: 清除後記憶體區域不連續,産生過多垃圾碎片,導緻後續配置設定大對象時容易發生記憶體不足而觸發另一次垃圾收集動作。

後續的收集算法都是标記-清除算法的更新版本,沿用了先标記後清除的思想。

複制算法

複制算法将記憶體區域分成兩部分,每次隻使用其中一部分,當一邊記憶體用完時,将這部分對象全部複制到另一塊區域,然後将該部分記憶體全部清除。

優點:

優化了标記-清除算法的記憶體碎片問題,每次垃圾收集之後得到的是一塊連續的記憶體區域。

缺點

空間代價較大,有一半記憶體空間一直是空閑狀态。

在JVM中的使用

應用于新生代收集算法, 新生代将記憶體分為一塊較大的Eden和兩塊較小的Survivor空間,每次使用Eden和其他一塊Survivor區,每當垃圾回收時,将Eden區和Survivor區中存活的對象全部複制到另一塊Survivor中。最後清理掉Eden和Survivor 。

其中, Eden和Survivor的預設比例為8:1:1。 因為據研究表明,新生代中的98%對象都會在第一次就回收,是以隻需要較小的空閑空間進行複制。那麼特殊的情況下,Survivor空間不夠時,需要依賴于堆記憶體中的老年代進行配置設定。

标記-整理算法

複制收集算法在對象存活率較高時就要進行較多的複制操作,效率将變得低下。

标記整理算法和清除算法的流程大緻相同,隻是多了一步整理, 順序是 标記-整理-清除。

整理是指,将存活對象,往記憶體某一端移動,移動完成後,然後将後續空間全部清除。

分代收集算法

分代收集算法隻是一種思想,他是将記憶體區域分成多塊,然後根據不同區域的特點采用不同的收集算法。

例如: 新生代對象疊代快 采用的是複制算法。老年代對象存活時間長,采用标記整理算法。

繼續閱讀