Java中的四種引用類型

簡介

從JDK1.2版本開始,把對象的引用分爲四種級別,從而使程序能更加靈活的控制對象的生命週期。這四種級別由高到低依次爲:強引用軟引用弱引用虛引用,下面分別介紹下這四種引用。java

強引用

強引用是最經常使用的引用類型,以下所示,new Object()會建立一個Object對象並存儲在堆上,變量object存儲對該對象的強引用。數組

Object object = new Object();

強引用不會被垃圾回收,因此要想回收該對象,則應該將指向該對象的變量顯示設爲null,這樣該對象就由強引用轉變爲無引用了。緩存

示例:ide

public class ReferenceDemo {
    public static void main(String[] args) throws IOException {
        //強引用不會被垃圾回收
        ReferenceDemo referenceDemo = new ReferenceDemo();
        //強引用轉變爲無引用,無引用可被垃圾回收
        referenceDemo = null;
        //觸發垃圾回收
        System.gc();
        //阻塞主線程,等待垃圾回收線程執行
        System.in.read();
    }

    //對象被回收以前調用
    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        System.out.println("-----finalize-----");
    }
}

軟引用

軟引用是使用SoftReference建立的,在內存空間充足的狀況下,軟引用不會被回收,而在內存空間不足虛擬機拋出OutOfMemoryError以前,軟引用將會被回收。線程

示例:code

public class ReferenceDemo {
    public static void main(String[] args) throws InterruptedException {
        //建立ReferenceDemo對象的軟引用
        SoftReference<ReferenceDemo> softReference = new SoftReference<>(new ReferenceDemo());
        //觸發垃圾回收
        System.gc();
        //阻塞主線程,等待垃圾回收線程執行
        Thread.sleep(5000);
        //softReference.get()返回軟引用對象,若是對象已經被垃圾回收,則返回null
        System.out.println(softReference.get());

        //建立25M的字節數組
        byte[] bytes = new byte[1024 * 1024 * 25];
        //內存已經不足,阻塞主線程,等待垃圾回收線程執行
        Thread.sleep(5000);
        //從新輸出軟引用對象
        System.out.println(softReference.get());
    }
}

/*
 * 輸出結果:
 * com.buhe.demo.demos.reference.ReferenceDemo@76fb509a
 * null
 */

注意:示例運行前須要設置堆內存大小爲30M(-Xmx30m -Xms30m)。對象

用途:軟引用能夠用於對內存空間敏感的緩存,緩存的對象一直保存,直到內存空間不足而被回收。生命週期

弱引用

弱引用是使用WeakReference建立的,在垃圾回收線程執行過程當中,只要找到了弱引用,無論內存空間是否足夠,弱引用對象都將被回收。因爲垃圾回收線程是一個優先級很低的線程,所以不必定會很快發現那些只具備弱引用的對象。隊列

示例:內存

public class ReferenceDemo {
    public static void main(String[] args) throws InterruptedException {
        //建立ReferenceDemo的弱引用
        WeakReference<ReferenceDemo> weakReference = new WeakReference<>(new ReferenceDemo());
        //weakReference.get()返回弱引用對象,若是對象已經被垃圾回收,則返回null
        System.out.println(weakReference.get());

        //觸發垃圾回收
        System.gc();
        //阻塞主線程,等待垃圾回收線程執行
        Thread.sleep(3000);

        //從新輸出弱引用對象
        System.out.println(weakReference.get());
    }
}

/*
 * 輸出結果:
 * com.buhe.demo.demos.reference.ReferenceDemo@76fb509a
 * null
 */

用途:弱引用也能夠用於緩存,能夠參考WeakHashMap類。

虛引用

虛引用是使用PhantomReference建立的,它是因此引用類型中最弱的。虛引用對象和沒有引用的對象相同,能夠在任什麼時候候被垃圾回收,而且虛引用必需要與引用隊列一塊兒使用。

當垃圾回收線程回收一個虛引用對象時,它將在垃圾回收後銷燬該對象,並將PhantomReference添加到引用隊列中。

示例:

public class ReferenceDemo {
    public static void main(String[] args) throws InterruptedException {
        //建立引用隊列
        ReferenceQueue<Object> referenceQueue = new ReferenceQueue();
        //建立ReferenceDemo的虛引用
        PhantomReference<ReferenceDemo> phantomReference = new PhantomReference<>(new ReferenceDemo(), referenceQueue);
        //phantomReference.get()老是返回null
        System.out.println("phantomReference.get():" + phantomReference.get());
        //輪詢此隊列,查看是否有可用的Reference對象,有則返回該對象,不然返回null
        System.out.println("referenceQueue.poll():" + referenceQueue.poll());

        //觸發垃圾回收
        System.gc();
        //阻塞主線程,等待垃圾回收線程執行
        Thread.sleep(3000);
        System.out.println("------垃圾回收以後------");

        System.out.println("phantomReference.get():" + phantomReference.get());
        System.out.println("referenceQueue.poll():" + referenceQueue.poll());
    }
}

/*
 * 輸出結果:
 * phantomReference.get():null
 * referenceQueue.poll():null
 * ------垃圾回收以後------
 * phantomReference.get():null
 * referenceQueue.poll():java.lang.ref.PhantomReference@76fb509a
 */

用途:虛引用能夠用於精確的檢測對象什麼時候從內存中刪除,經過檢查引用隊列來判斷對象是否已經被回收。

相關文章
相關標籤/搜索