JVM系列之JVM垃圾回收算法相關知識
今天給大家繼續分享JVM垃圾回收算法相關知識。
JVM垃圾回收算法主要有標記清除、復制算法、標記整理、分代收集四種,下面來逐一介紹。
1、標記清除(Mark-Sweep)
標記清除作為最基礎的垃圾回收算法,其過程要經歷兩個階段:標記、回收。
標記:遍歷內存區域,標記出待回收的對象。
回收:再次遍歷內存區域,然后對已標記的對象占用的內存進行回收。
缺點:
- 需要遍歷兩次內存區域,效率低。
- 因為JVM存儲特點是邏輯上連續,物理上可以不連續,標記清除算法可能產生大量內存碎片,當JVM需要一塊比較大的內存空間的時候,而又找不到合適的內存空間,就會觸發下一次的垃圾回收操作。
2、復制算法(Copy)
復制算法主要是解決標記—清除算法遍歷的和產生內存碎片的缺點,在其基礎上進行改進而來的,它會將可用內存按容量分為大小相等的兩塊,每次只能使用其中的一塊,當正在使用的這一塊的內存空間不滿足使用的時候,就會將還存活的對象復制到另外一塊空的內存上面,然后再把當前內存空間一次清理掉。
復制算法在新生代中兩個幸存區(From 、To)的不停交換是最典型的用法。
新生代內存空間占比為 8(Eden 伊甸園區 ):1 (To Survivor):1 (Survivor From)。
優點
- 內存回收時,不會產生內存碎片
- 回收的時候只需移動棧頂指針,按順序分配內存即可,實現簡單
- 每次只對兩塊中的一塊內存進行回收,效率高
- 復制算法執行后,空間時連續的。
缺點:
一次性分配內存只能用其中的一半,內存的最大可利用率只有一半。
3、標記整理(Mark-Compact)
標記整理算法主要是針對老年代來設計的。
執行過程:
- 標記:對需要回收對象的進行標記。
- 整理:讓存活的對象,向內存的一端移動,在整理的過程中,之前對象的在虛擬機棧中的引用地址也隨之發生改變,最后直接清理掉非存活對象的內存空間。
優點:
- 沒有碎片化內存產生(標記清除算法比較)。
- 沒有了內存利用率減半的消耗(復制算法比較)。
缺點:
- 效率相比標記復制算法稍低。
- 在整理存活對象過程中,因為存活對象位置點變動,需要調整對象在虛擬機棧中的引用地址,同時需要全程暫停用戶線程,STW(Stop The World)。
4、分代收集算法
嚴格意義上來說分代收集不能算一種新的垃圾回收算法,分代收集其實只是根據對象的存活的時間的長短,將新生代和老年代針對不同的內存區域,采取對應的算法。目前市面上大多商用虛擬機都采用分代收集算法。
新生代:每次都有大量對象消亡,因為有老年代作為內存擔保,比較采取復制算法。
老年代:對象存活時間長,可采用標記整理、標記清除算法。
5、三種垃圾回收算法對比
對比參數 | 標記清除 | 標記整理 | 標記復制 |
速度 | 中等 | 最慢 | 最快 |
空間開銷 | 少(會產生碎片) | 少(不會產生碎片) | 2倍開銷 |
移動對象 | 否 | 是 | 是 |
適合場景 | 老年代 | 老年代 | 新生代 |