1. 程式人生 > >JVM學習--垃圾收集演算法

JVM學習--垃圾收集演算法

JVM學習–總索引

文章目錄

JVM學習–垃圾收集演算法

本文主要介紹幾種常用演算法的思想,包括標記-清除演算法,標記-整理演算法,複製演算法,分代收集演算法。

標記-清除演算法

在這裡插入圖片描述
步驟:
1.如上面的示意圖所示,在垃圾回收前,先將記憶體中標記哪些物件可以被回收。
2.回收那些被標記的物件
存在的問題:
1.標記和回收過程的效率都不高。
2.由於回收之後,會產生大量的不連續i記憶體,當後面申請的是大物件記憶體,不容易找到合適的記憶體區塊。該演算法極易會造成空間的浪費。

複製演算法

在這裡插入圖片描述
步驟:
1.該演算法將記憶體分為兩個區塊,其中一個區塊用於分配記憶體,另一個區塊不會使用,也就是保留區域。
2.當進行垃圾回收時,會將存活的物件複製到保留區域。
3.對先前分配的記憶體的那一部分一次清理掉,並標記為保留區域。
優點:每次都是對一整片進行垃圾回收,因此效率比較高。
缺點:由於記憶體被分為兩個區塊,導致有50%的記憶體不能被使用,造成空間的浪費。

有些演算法對此進行了優化,不再是1:1的比例分割槽塊。
在這裡插入圖片描述

而是將記憶體分為一塊較大的Eden區,和兩塊較小的Survivor區作為新生代區,還有另一塊老年代區。
每次使用Eden和其中一塊Survivor區,當進行垃圾回收時,就 將還存活的物件從Eden和From Survivor區複製到To Survivor區,然後一次性清理掉剛才使用的Eden和From Survivor區。相比於上面的複製演算法,增加了記憶體空間的利用率。HotSpot的Eden 和Survivor的預設比例是8:1,也就是8(Eden ):1(From Survivor):1(To Survivor),每次都能使用90%的空間,只有10%的空間浪費。
由於不能確保每次存活的物件佔用的記憶體不低於Survivor的空間,因此增加了老年代,Survivor的空間不夠,那麼多出來的物件可以直接放到老年代中去。不僅如此,有些大物件在建立時也會直接在老年代區分配記憶體,有些經過多次垃圾回收沒有被回收的物件也會放置在老年代中去。
存在的缺點:
第一:當物件存活率較高時,會進行較多的複製操作,導致效率降低。
第二:需要額外的空間作擔保,比如老年代。

標記-整理演算法

在這裡插入圖片描述
由於老年代中的物件存活率較高,每次垃圾收集時只有少數的物件被回收。因此不適用於上面的複製演算法。使用標記-整理演算法比較好。
標記整理演算法就是先將可回收的物件標記為可回收物件,再將存活的物件往一端移動,最後直接將存活物件以外的區塊清理掉。

分代收集演算法。

分代收集演算法只是一種思想,本質上還是使用上面的演算法來解決。由於存在有的物件存活率高,有的物件存活率低,因此就提出了分代的思想。新生代中的物件物件存活率低,每次垃圾回收都能夠回收大部分的物件,因此使用複製演算法比較好,只需要複製少量的存活物件,效率比較高。但是老年代的物件存活率高,並且沒有額外的空間作擔保,不適合使用複製演算法,就需要使用“標記-清除”或者“標記-整理”演算法。