Java引用類型

Java有四種引用類型,strongreference,softreference,weakreference,phantomreference。這四種引用的強(qiáng)度按照上面的順序依次減弱,下面通過幾個(gè)例子簡單了解一下這四種引用類型。

StrongReference

這個(gè)不用多講了,這是java默認(rèn)的引用類型,如果不特意使用java.lang.ref下的類,那么程序中的所有引用都是強(qiáng)引用。有強(qiáng)引用存在的對象永遠(yuǎn)都不會被gc收集,所以在內(nèi)存不夠用時(shí),JVM寧愿拋出OutOfMemoryError這樣的錯(cuò)誤,也不愿意將強(qiáng)引用對象進(jìn)行回收。

SoftReference

軟引用不會保證對象一定不會被回收,只能最大可能保證。如果內(nèi)存有剩余,那么軟引用對象不會被回收,如果內(nèi)存不足,那么gc會回收軟引用對象。所以這種特性可以用來實(shí)現(xiàn)緩存技術(shù)。軟引用要用java.lang.ref.SoftReference來實(shí)現(xiàn)。

Java代碼

publicclassSoftTest{

publicstaticvoidmain(String[]?args)?{

Object?ref?=newObject();//ref是Object對象的強(qiáng)引用

//將一個(gè)軟引用指向?qū)ο?,此時(shí)Object對象有兩個(gè)引用

SoftReference?sf?=newSoftReference(ref);

ref?=null;//去除對象的強(qiáng)引用

System.gc();//gc只有在內(nèi)存不足是才會回收軟引用對象

}

}

WeakReference

除了通過java.lang.ref.WeakReference來使用弱引用,WeakHashMap同樣也利用了弱引用。

和軟引用不同的是,弱引用一定會被gc回收,不管內(nèi)存是否不足。

Java代碼

publicclassWeakTest{

publicstaticvoidmain(String[]?args)?{

Object?ref?=newObject();//ref是Object對象的強(qiáng)引用

//將一個(gè)弱引用指向?qū)ο?,此時(shí)Object對象有兩個(gè)引用

WeakReference?wf?=newWeakReference(ref);

ref?=null;//去除對象的強(qiáng)引用

System.gc();//gc對弱引用對象進(jìn)行回收

}

}

PhantomReference

幽靈引用,也叫虛引用。java.lang.ref.PhantomReference類中只有一個(gè)方法get(),而且?guī)缀鯖]有實(shí)現(xiàn),只是返回null。而且這個(gè)類只有一個(gè)構(gòu)造器(軟引用和弱引用均有兩個(gè)構(gòu)造器):

Java代碼

publicPhantomReference(T?referent,?ReferenceQueue?q)?{

super(referent,?q);

}

也就是說,幽靈引用只能與ReferenceQueue(后面會提到這個(gè)類)一起使用。如果一個(gè)對象僅有幽靈引用,那么它就像沒有任何引用一樣,在任何時(shí)候都可能被gc回收。幽靈引用主要用來跟蹤對象被垃圾回收的活動(dòng)。

Java代碼

publicclassPhantomTest{

publicstaticvoidmain(String[]?args)?{

Object?ref?=newObject();//ref是Object對象的強(qiáng)引用

//將一個(gè)幽靈引用指向?qū)ο螅琍hantomReference必須與ReferenceQueue一同使用

PhantomReference?pf?=newPhantomReference(ref,newReferenceQueue());

System.out.println(pf.get());

}

}

ReferenceQueue

如果一個(gè)對象只有軟引用、弱引用或者幽靈引用,gc在回收對象時(shí),JVM會自動(dòng)將其引用放入一個(gè)ReferenceQueue中。WeakHashMap就是利用了ReferenceQueue來實(shí)現(xiàn)清除沒有強(qiáng)引用Entry的。將上面的弱引用例子稍微改一下:

Java代碼

publicclassReferenceQueueTest{

publicstaticvoidmain(String[]?args)?{

Object?ref?=newObject();//ref是Object對象的強(qiáng)引用

System.out.println(ref);

ReferenceQueue?rq=newReferenceQueue();//有強(qiáng)引用的ReferenceQueue

WeakReference?sf?=newWeakReference(ref,rq);//構(gòu)造弱引用時(shí)傳入ReferenceQueue

System.out.println(sf);

ref?=null;//去除對象的強(qiáng)引用,在這里加個(gè)斷點(diǎn),進(jìn)行調(diào)試

System.gc();//gc對弱引用對象進(jìn)行回收

System.out.println(rq.poll());

}

}

注意,運(yùn)行這個(gè)程序需要用debug模式進(jìn)行調(diào)試,在上面說明的地方加個(gè)斷點(diǎn)。如果直接運(yùn)行,結(jié)果很可能只是個(gè)null,用debug調(diào)試的話會看到輸出的是弱引用的地址。程序輸出的sf結(jié)果和rq.poll()結(jié)果相同。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 強(qiáng)引用 ( Strong Reference ) 強(qiáng)引用是使用最普遍的引用。如果一個(gè)對象具有強(qiáng)引用,那垃圾回收器絕...
    tomas家的小撥浪鼓閱讀 3,130評論 1 4
  • 概述 java.lang.ref 類庫包含一組類,為垃圾回收提供了更大的靈活性。 java.lang.ref 有三...
    bing__chen閱讀 485評論 0 2
  • 來源:朱小廝 鏈接:http://blog.csdn.net/u013256816/article/details...
    會點(diǎn)代碼的大叔閱讀 423評論 0 1
  • 歡迎訪問我的博客:http://wangnan.tech 參考: http://blog.csdn.net/mxb...
    GhostStories閱讀 416評論 0 1
  • 1.強(qiáng)引用:強(qiáng)引用是使用最普遍的引用。如果一個(gè)對象具有強(qiáng)引用,那垃圾回收器絕不會回收它。當(dāng)內(nèi)存空間不足,Java虛...
    shannonxizhang閱讀 236評論 0 0

友情鏈接更多精彩內(nèi)容