JVM學習記錄-垃圾回收算法
簡述
因為各個平臺的虛擬機的垃圾收集器的實現各有不同,所以只介紹幾個常見的垃圾收集算法。
JVM中常見的垃圾收集算法有以下四種:
標記-清除算法(Mark-Sweep)。
復制算法(Copying)。
標記整理算法(Mark-Compact)。
分代收集算法(Generational Collecting)。
標記-清除算法
標記-清除算法是現代垃圾回收算法的思想基礎,主要分為兩個階段:標記階段和清除階段。首先根據可達分析算法,標記處可以回收的對象,標記完成後,進行清除階段,將標記為可回收的對象進行清除。這個算法有兩個弱點,一個弱點是效率問題,標記和清除效率都不高,另一弱點,也是最大的弱點就是會產生空間碎片。當內存中空間碎片過多時,在創建較大的對象過程中,無法分配出足夠的聯系內存空間,會不得以的出發一次垃圾回收動作。
標記-清除算法執行過程如下圖所示:
復制算法
與標記-清除算法相比,復制算法是一種相對效率高的回收算法,它的核心思想是:將原有的內存空間劃分為大小相等的兩塊,每次只使用其中一塊,在垃圾回收時,將正在使用的內存中的存活的對象復制到未使用的的內存塊中,然後清除正在使用的內存塊,然後交換兩個內存的角色(即使用塊變成未使用塊,未使用塊變成使用塊)。復制算法可以保證回收後沒有空間碎片。但是復制算法的弱點是將系統可用內存折半,這個代價有些太大。
執行過程如下:
在JVM的新生代(堆內存分為新生代和老年代)中就是使用的這種收集算法,在新生代中大部分對象都是“朝生夕死”,所以復制算法也不是非要按照對半平分內存,而是分為較大的一個Eden
復制算法適用於新生代,是因為在新生代中,垃圾對象通常多於存活對象,這中情況適用復制算法效果會比較好。
標記整理算法
復制算法的高效性,是因為新生代的存活對象多,垃圾對象少。但是在老年代中,常見的情況下大部分都是存活對象,如果依然只用復制算法,效率就會大大折扣。因為存活對象太多,復制的成本太高了。
基於老年代的特點,產生了一種標記整理算法,標記整理算法也是分兩個階段,標記階段和整理階段,標記階段也是先標記出存活的對象,在整理階段是將存活的對象都向內存的一端進行壓縮移動,然後清理掉端邊界以外的空間。
標記整理算法執行過程如下:
這種算法既避免了產生空間碎片,又不需要將內存平分,因此效率還是可以的。
分代收集算法
當前的商業虛擬機都采用“分代收集算法”,其主要思想是:根據垃圾回收對象的特性,使用合適的算法進行回收。基於這種思想,分代算法將堆內存分為特點鮮明的幾塊,根據每塊的特點,選擇適用的收集算法,進而提高回收效率。
在新生代時使用復制算法,在老年代時使用標記壓縮算法。
這種分代算法在HotSpot虛擬機上使用,幾乎所有的垃圾回收器都區分新生代和老年代。
JVM學習記錄-垃圾回收算法