天天看點

JVMGC——基本垃圾回收算法

虛拟機的回收算法按照基本回收政策分為以下四種:

1. 引用計數

原理是此對象有一個引用就增加一個計數,删除一個引用則減少一個計數。垃圾回收時,隻回收計數為0的對象。

缺點:無法處理循環引用的問題

2.  标記-清除 , 是老年代(Tenured)的主要回收算法

JVMGC——基本垃圾回收算法

此算法執行分兩階段:

1. 從引用根節點開始标記所有被引用的對象

2. 周遊整個堆,把未标記的對象清除。

缺點:此算法需要暫停整個應用,會産生記憶體碎片

3.複制,是年輕代的主要垃圾回收算法

JVMGC——基本垃圾回收算法

此算法把記憶體空間劃為兩個相等的區域,每次隻使用其中一個區域。

垃圾回收時,周遊目前使用區域,把正在使用中的對象複制到另外一個區域,之後進行相應的記憶體整理,不會出現碎片問題。

缺點:需要兩倍記憶體空間

4. 标記-整理 

JVMGC——基本垃圾回收算法

在标記-清除之後重新整理記憶體,避免了記憶體碎片問題和複制算法的空間問題

記憶體碎片會導緻無法配置設定大塊的記憶體空間以及程式運作效率降低

哪些對象可以被稱為“垃圾”

垃圾回收的起點是一些根對象:

1.沒有被任何外部對象引用的棧中的對象,即系統内運作的所有線程配置設定在棧中的變量,該對象就是“根”

一旦線程跑到某一個變量所在的作用域之外,那麼該變量就變成了垃圾

2.靜态變量在任何時候都是“根”對象

3.寄存器

根據這些根集對象檢測所有對象的可達性即可判斷對象是否可以回收

可達性:某個對象的記憶體位址是否有被引用

把一個對象置為NULL并不能保證該對象會被回收

測試類:

public class TestNull {

    public static void main(String[] args) {
        Map<String, Object> map = new HashMap<>();
        Object obj = new Object();
        map.put("obj", obj);
        obj = null;
        System.out.println(map.get("obj"));
    }

}
           

運作可以看到map仍然可以引用到obj,分析如圖:

JVMGC——基本垃圾回收算法

因為HashMap仍然引用了new Object()對象,是以其并不會被JVM回收

tips:

1.如果希望集合中的對象被回收,調用其相應的remove()方法從集合中删掉即可

2.obj = null;語義是把讓變量obj不再指向任何實體記憶體

而不是把obj所指向的對象的實體記憶體置為null

繼續閱讀