1. 程式人生 > >JVM學習--強引用,軟引用,弱引用,虛引用

JVM學習--強引用,軟引用,弱引用,虛引用

JVM學習–總索引

文章目錄

JVM學習–強引用,軟引用,弱引用,虛引用

強引用

強引用就是程式碼中通過常規方法建立的物件,比如new,反序列化,反射等方式建立的物件。只要強引用還存在,那麼垃圾收集器就不會回收該物件。

軟引用

如果一個物件只具有軟引用,則記憶體空間足夠,垃圾回收器就不會回收它;如果記憶體空間不足了,就會回收這些物件的記憶體。只要垃圾回收器沒有回收它,該物件就可以被程式使用。軟引用可用來實現記憶體敏感的快取記憶體(下文給出示例)。
軟引用可以和一個引用佇列(ReferenceQueue)聯合使用,如果軟引用所引用的物件被垃圾回收器回收,Java虛擬機器就會把這個軟引用加入到與之關聯的引用佇列中。
Java中使用SoftReference類來實現。

弱引用

弱引用與軟引用的區別在於:只具有弱引用的物件擁有更短暫的生命週期。在垃圾回收器執行緒掃描它所管轄的記憶體區域的過程中,一旦發現了只具有弱引用的物件,不管當前記憶體空間足夠與否,都會回收它的記憶體。不過,由於垃圾回收器是一個優先順序很低的執行緒,因此不一定會很快發現那些只具有弱引用的物件。
弱引用可以和一個引用佇列(ReferenceQueue)聯合使用,如果弱引用所引用的物件被垃圾回收,Java虛擬機器就會把這個弱引用加入到與之關聯的引用佇列中。
Java中使用WeakReference類來實現。

虛引用

“虛引用”顧名思義,就是形同虛設,與其他幾種引用都不同,虛引用並不會決定物件的生命週期。如果一個物件僅持有虛引用,那麼它就和沒有任何引用一樣,在任何時候都可能被垃圾回收器回收。
虛引用主要用來跟蹤物件被垃圾回收器回收的活動。虛引用與軟引用和弱引用的一個區別在於:虛引用必須和引用佇列 (ReferenceQueue)聯合使用。當垃圾回收器準備回收一個物件時,如果發現它還有虛引用,就會在回收物件的記憶體之前,把這個虛引用加入到與之 關聯的引用佇列中。
Java中使用PhantomReference類來實現。

例子

public class ReferenceDemo {

    private String name;

    public ReferenceDemo(String name) {
        this.name = name;
    }

    public static void main(String[] args) {

		//建立強引用物件
        ReferenceDemo demo1 = new ReferenceDemo("AA");
        ReferenceDemo demo2 = new ReferenceDemo("BB"
); ReferenceDemo demo3 = new ReferenceDemo("CC"); ReferenceDemo demo4 = new ReferenceDemo("DD"); ReferenceDemo demo5 = new ReferenceDemo("FF"); ReferenceDemo demo6 = new ReferenceDemo("EE"); //關聯軟引用 SoftReference<ReferenceDemo> soft1 = new SoftReference<ReferenceDemo>(demo1); SoftReference<ReferenceDemo> soft2 = new SoftReference<ReferenceDemo>(demo2); //關聯弱引用 WeakReference<ReferenceDemo> soft3 = new WeakReference<ReferenceDemo>(demo3); WeakReference<ReferenceDemo> soft4 = new WeakReference<ReferenceDemo>(demo4); //關聯虛引用 ReferenceQueue<ReferenceDemo> queue = new ReferenceQueue<ReferenceDemo>(); PhantomReference<ReferenceDemo> soft5 = new PhantomReference<ReferenceDemo>(demo5,queue); // PhantomReference<ReferenceDemo> soft6 = new PhantomReference<ReferenceDemo>(demo6); //去除強引用 demo1 = null; demo2 = null; demo3 = null; demo4 = null; System.gc(); print(soft1); print(soft2); print(soft3); print(soft4); print(soft5); } public static void print(Reference<ReferenceDemo> reference){ ReferenceDemo demo = (ReferenceDemo)reference.get(); if(demo == null){ System.out.println(reference.getClass()+" value = null"); } else{ System.out.println(reference.getClass()+" value = " + demo.getName()); } } public String getName() { return name; } public void setName(String name) { this.name = name; } }

當 demo3 = null; demo4 = null; 不存在時
輸出

class java.lang.ref.SoftReference value = AA
class java.lang.ref.SoftReference value = BB
class java.lang.ref.WeakReferenceis value = CC
class java.lang.ref.WeakReferenceis value = DD
class java.lang.ref.PhantomReferenceis value = null

當 demo3 = null; demo4 = null; 存在時
輸出

class java.lang.ref.SoftReference value = AA
class java.lang.ref.SoftReference value = BB
class java.lang.ref.WeakReferenceis value = null
class java.lang.ref.WeakReferenceis value = null
class java.lang.ref.PhantomReferenceis value = null

從上面可以看出

  • 虛引用關聯的物件是無法獲取到的。
  • 軟引用關聯的物件在垃圾回收時,記憶體空間足夠,垃圾回收器就不會回收它。
  • 弱引用關聯的物件在垃圾回收時,如果物件的強引用不存在,不管記憶體空間夠不夠,都會被回收。