從Java SE2開始伊脓,就提供了四種類型的引用:強引用分蓖、軟引用唱凯、弱引用和虛引用。
Java中提供這四種引用類型主要有兩個目的:
讓程序員通過代碼的方式?jīng)Q定某些對象的生命周期睛低;
第二是有利于JVM進行垃圾回收案狠。
一、持有不同類型引用的對象回收規(guī)則
強引用:無論內(nèi)存是否足夠钱雷,不會回收骂铁。
軟引用:內(nèi)存不足時,回收該引用關(guān)聯(lián)的對象罩抗。
弱引用:垃圾回收時拉庵,無論內(nèi)存是否足夠,都會回收套蒂。
虛引用:任何時候都可能被垃圾回收器回收钞支。
1. 強引用
強引用是我們使用的最廣泛,也是最普遍的一種引用類型泣懊。
Object object = new Object();
只要某個對象有強引用與之關(guān)聯(lián)伸辟,JVM必定不會回收這個對象,即使在內(nèi)存不足的情況下馍刮,JVM寧愿拋出OutOfMemory錯誤也不會回收這種對象信夫。如果想中斷強引用和某個對象之間的關(guān)聯(lián),可以顯示地將引用賦值為null卡啰,這樣一來的話静稻,JVM在合適的時間就會回收該對象。
2. 軟引用
軟引用是用來描述一些有用但并不是必需的對象匈辱,在Java中用java.lang.ref.SoftReference類來表示振湾。對于軟引用關(guān)聯(lián)著的對象,只有在內(nèi)存不足的時候JVM才會回收該對象亡脸。因此押搪,這一點可以很好地用來解決OOM的問題树酪,并且這個特性很適合用來實現(xiàn)緩存:比如網(wǎng)頁緩存、圖片緩存等大州。
SoftReference<String> sr = new SoftReference<String>(new String("賭書消得潑茶香"));
System.out.println(sr.get());
軟引用可以和一個引用隊列(ReferenceQueue)聯(lián)合使用续语,如果軟引用所引用的對象被JVM回收,這個軟引用就會被加入到與之關(guān)聯(lián)的引用隊列中厦画。當(dāng)一個obj被gc掉之后疮茄,其相應(yīng)的包裝類,即ref對象會被放入queue中根暑。我們可以從queue中獲取到相應(yīng)的對象信息力试,同時進行額外的處理。比如反向操作排嫌,數(shù)據(jù)清理等畸裳。
3. 弱引用
弱引用也是用來描述非必需對象的,當(dāng)JVM進行垃圾回收時淳地,無論內(nèi)存是否充足躯畴,都會回收被弱引用關(guān)聯(lián)的對象。在java中薇芝,用java.lang.ref.WeakReference類來表示。
WeakReference<String> sr = new WeakReference<String>(new String("賭書消得潑茶香"));
System.out.println(sr.get());
System.gc(); //通知JVM的gc進行垃圾回收
System.out.println(sr.get()); //輸出一定為null
不過要注意的是丰嘉,這里所說的被弱引用關(guān)聯(lián)的對象是指只有弱引用與之關(guān)聯(lián)夯到,如果存在強引用同時與之關(guān)聯(lián),則進行垃圾回收時也不會回收該對象(軟引用也是如此)饮亏。弱引用也可以和一個引用隊列(ReferenceQueue)聯(lián)合使用耍贾。
4. 虛引用
虛引用和前面的軟引用、弱引用不同路幸,它并不影響對象的生命周期荐开。在java中用java.lang.ref.PhantomReference類表示。如果一個對象與虛引用關(guān)聯(lián)简肴,則跟沒有引用與之關(guān)聯(lián)一樣晃听,在任何時候都可能被垃圾回收器回收。
要注意的是砰识,虛引用必須和引用隊列關(guān)聯(lián)使用能扒,當(dāng)垃圾回收器準備回收一個對象時,如果發(fā)現(xiàn)它還有虛引用辫狼,就會把這個虛引用加入到與之關(guān)聯(lián)的引用隊列中初斑。程序可以通過判斷引用隊列中是否已經(jīng)加入了虛引用,來了解被引用的對象是否將要被垃圾回收膨处。如果程序發(fā)現(xiàn)某個虛引用已經(jīng)被加入到引用隊列见秤,那么就可以在所引用的對象的內(nèi)存被回收之前采取必要的行動砂竖。
ReferenceQueue<String> queue = new ReferenceQueue<String>();
PhantomReference<String> pr = new PhantomReference<String>(new String("賭書消得潑茶香"), queue);
System.out.println(pr.get());
引用隊列可以和弱引用、軟引用聯(lián)合使用鹃答,虛引用必須與ReferenceQueue一起使用
5乎澄、引用隊列ReferenceQueue
ReferenceQueue主要是用于監(jiān)聽Reference所指向的對象是否已經(jīng)被垃圾回收。
當(dāng)大量使用Reference時挣跋,雖然Reference指向的對象可能被回收了三圆,但Reference本身也是個對象,所以也需要回收避咆。這時就需要使用ReferenceQueue了舟肉。
當(dāng)SoftReference或WeakReference的get()加入ReferenceQueue或get()返回null時,僅是表明其指示的對象已經(jīng)進入垃圾回收流程查库,此時對象不一定已經(jīng)被垃圾回收路媚。
當(dāng)PhantomReference加入ReferenceQueue時,則表明對象已經(jīng)被回收樊销。
參考鏈接
http://www.cnblogs.com/alias-blog/p/5793108.html
https://blog.csdn.net/houlin_jing/article/details/77986698