Java常見(jiàn)的四種引用是什么

這篇文章主要講解了“Java常見(jiàn)的四種引用是什么”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“Java常見(jiàn)的四種引用是什么”吧!

創(chuàng)新互聯(lián)長(zhǎng)期為1000多家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對(duì)不同對(duì)象提供差異化的產(chǎn)品和服務(wù);打造開(kāi)放共贏平臺(tái),與合作伙伴共同營(yíng)造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為姑蘇企業(yè)提供專業(yè)的成都網(wǎng)站設(shè)計(jì)、網(wǎng)站制作、外貿(mào)營(yíng)銷網(wǎng)站建設(shè)姑蘇網(wǎng)站改版等技術(shù)服務(wù)。擁有十年豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開(kāi)發(fā)。

從JDK1.2版本開(kāi)始,把對(duì)象的引用分為四種級(jí)別,從而使程序能更加靈活的控制對(duì)象的生命周期。這四種級(jí)別由高到低依次為:強(qiáng)引用、軟引用、弱引用和虛引用。

1.強(qiáng)引用

本章前文介紹的引用實(shí)際上都是強(qiáng)引用,這是使用最普遍的引用。如果一個(gè)對(duì)象具有強(qiáng)引用,那就 類似于必不可少的生活用品,垃圾回收器絕不會(huì)回收它。當(dāng)內(nèi)存空 間不足,Java虛擬機(jī)寧愿拋出OutOfMemoryError錯(cuò)誤,使程序異常終止,也不會(huì)靠隨意回收具有強(qiáng)引用的對(duì)象來(lái)解決內(nèi)存不足問(wèn)題。

2.軟引用(SoftReference)

如果一個(gè)對(duì)象只具有軟引用,那就類似于可有可物的生活用品。如果內(nèi)存空間足夠,垃圾回收器就不會(huì)回收它,如果內(nèi)存空間不足了,就會(huì)回收這些對(duì)象的內(nèi)存。只要垃圾回收器沒(méi)有回收它,該對(duì)象就可以被程序使用。軟引用可用來(lái)實(shí)現(xiàn)內(nèi)存敏感的高速緩存。
軟引用可以和一個(gè)引用隊(duì)列(ReferenceQueue)聯(lián)合使用,如果軟引用所引用的對(duì)象被垃圾回收,Java虛擬機(jī)就會(huì)把這個(gè)軟引用加入到與之關(guān)聯(lián)的引用隊(duì)列中。

3.弱引用(WeakReference)

如果一個(gè)對(duì)象只具有弱引用,那就類似于可有可物的生活用品。 弱引用與軟引用的區(qū)別在于:只具有弱引用的對(duì)象擁有更短暫的生命周期。在垃圾回收器線程掃描它 所管轄的內(nèi)存區(qū)域的過(guò)程中,一旦發(fā)現(xiàn)了只具有弱引用的對(duì)象,不管當(dāng)前內(nèi)存空間足夠與否,都會(huì)回收它的內(nèi)存。不過(guò),由于垃圾回收器是一個(gè)優(yōu)先級(jí)很低的線程, 因此不一定會(huì)很快發(fā)現(xiàn)那些只具有弱引用的對(duì)象。
弱引用可以和一個(gè)引用隊(duì)列(ReferenceQueue)聯(lián)合使用,如果弱引用所引用的對(duì)象被垃圾回收,Java虛擬機(jī)就會(huì)把這個(gè)弱引用加入到與之關(guān)聯(lián)的引用隊(duì)列中。

4.虛引用(PhantomReference)

"虛引用"顧名思義,就是形同虛設(shè),與其他幾種引用都不同,虛引用并不會(huì)決定對(duì)象的生命周期。如果一個(gè)對(duì)象僅持有虛引用,那么它就和沒(méi)有任何引用一樣,在任何時(shí)候都可能被垃圾回收。
虛 引用主要用來(lái)跟蹤對(duì)象被垃圾回收的活動(dòng)。虛引用與軟引用和弱引用的一個(gè)區(qū)別在于:虛引用必須和引用隊(duì)列(ReferenceQueue)聯(lián)合使用。當(dāng)垃 圾回收器準(zhǔn)備回收一個(gè)對(duì)象時(shí),如果發(fā)現(xiàn)它還有虛引用,就會(huì)在回收對(duì)象的內(nèi)存之前,把這個(gè)虛引用加入到與之關(guān)聯(lián)的引用隊(duì)列中。程序可以通過(guò)判斷引用隊(duì)列中是 否已經(jīng)加入了虛引用,來(lái)了解被引用的對(duì)象是否將要被垃圾回收。程序如果發(fā)現(xiàn)某個(gè)虛引用已經(jīng)被加入到引用隊(duì)列,那么就可以在所引用的對(duì)象的內(nèi)存被回收之前采取必要的行動(dòng)。

在本書中,"引用"既可以作為動(dòng)詞,也可以作為名詞,讀者應(yīng)該根據(jù)上下文來(lái)區(qū)分"引用"的含義。

在java.lang.ref包中提供了三個(gè)類:SoftReference類、WeakReference類和PhantomReference 類,它 們分別代表軟引用、弱引用和虛引用。ReferenceQueue類表示引用隊(duì)列,它可以和這三種引用類聯(lián)合使用,以便跟蹤Java虛擬機(jī)回收所引用的對(duì) 象的活動(dòng)。以下程序創(chuàng)建了一個(gè)String對(duì)象、ReferenceQueue對(duì)象和WeakReference對(duì)象:

//創(chuàng)建一個(gè)強(qiáng)引用 String str = new String("hello"); //創(chuàng)建引用隊(duì)列, <String>為范型標(biāo)記,表明隊(duì)列中存放String對(duì)象的引用 ReferenceQueue<String> rq = new ReferenceQueue<String>(); //創(chuàng)建一個(gè)弱引用,它引用"hello"對(duì)象,并且與rq引用隊(duì)列關(guān)聯(lián) //<String>為范型標(biāo)記,表明WeakReference會(huì)弱引用String對(duì)象 WeakReference<String> wf = new WeakReference<String>(str, rq);

以上程序代碼執(zhí)行完畢,內(nèi)存中引用與對(duì)象的關(guān)系如圖11-10所示。

Java常見(jiàn)的四種引用是什么

圖11-10 "hello"對(duì)象同時(shí)具有強(qiáng)引用和弱引用

在圖11-10中,帶實(shí)線的箭頭表示強(qiáng)引用,帶虛線的箭頭表示弱引用。從圖中可以看出,此時(shí)"hello"對(duì)象被str強(qiáng)引用,并且被一個(gè)WeakReference對(duì)象弱引用,因此"hello"對(duì)象不會(huì)被垃圾回收。

在以下程序代碼中,把引用"hello"對(duì)象的str變量置為null,然后再通過(guò)WeakReference弱引用的get()方法獲得"hello"對(duì)象的引用:

String str = new String("hello"); //① ReferenceQueue<String> rq = new ReferenceQueue<String>(); //② WeakReference<String> wf = new WeakReference<String>(str, rq); //③ str=null; //④取消"hello"對(duì)象的強(qiáng)引用 String str1=wf.get(); //⑤假如"hello"對(duì)象沒(méi)有被回收,str1引用"hello"對(duì)象 //假如"hello"對(duì)象沒(méi)有被回收,rq.poll()返回null Reference<? extends String> ref=rq.poll(); //⑥

執(zhí)行完以上第④行后,內(nèi)存中引用與對(duì)象的關(guān)系如圖11-11所示,此 時(shí)"hello"對(duì)象僅僅具有弱引用,因此它有可能被垃圾回收。假如它還沒(méi)有被垃圾回收,那么接下來(lái)在第⑤行執(zhí)行wf.get()方法會(huì)返 回"hello"對(duì)象的引用,并且使得這個(gè)對(duì)象被str1強(qiáng)引用。再接下來(lái)在第⑥行執(zhí)行rq.poll()方法會(huì)返回null,因?yàn)榇藭r(shí)引用隊(duì)列中沒(méi)有任 何引用。ReferenceQueue的poll()方法用于返回隊(duì)列中的引用,如果沒(méi)有則返回null。

Java常見(jiàn)的四種引用是什么

圖11-11 "hello"對(duì)象只具有弱引用

在以下程序代碼中,執(zhí)行完第④行后,"hello"對(duì)象僅僅具有弱引用。接下來(lái)兩次調(diào)用System.gc()方法,催促垃圾回收器工作,從而提 高"hello"對(duì)象被回收的可能性。假如"hello"對(duì)象被回收,那么WeakReference對(duì)象的引用被加入到ReferenceQueue 中,接下來(lái)wf.get()方法返回null,并且rq.poll()方法返回WeakReference對(duì)象的引用。圖11-12顯示了執(zhí)行完第⑧行后 內(nèi)存中引用與對(duì)象的關(guān)系。

String str = new String("hello"); //① ReferenceQueue<String> rq = new ReferenceQueue<String>(); //② WeakReference<String> wf = new WeakReference<String>(str, rq); //③ str=null; //④ //兩次催促垃圾回收器工作,提高"hello"對(duì)象被回收的可能性 System.gc(); //⑤ System.gc(); //⑥ String str1=wf.get(); //⑦ 假如"hello"對(duì)象被回收,str1為null Reference<? extends String> ref=rq.poll(); //⑧

Java常見(jiàn)的四種引用是什么

圖11-12 "hello"對(duì)象被垃圾回收,弱引用被加入到引用隊(duì)列

The important part about strong references -- the part that makes them "strong" -- is how they interact with the garbage collector. Specifically, if an object is reachable via a chain of strong references (strongly reachable), it is not eligible for garbage collection. As you don't want the garbage collector destroying objects you're working on, this is normally exactly what you want.

package com.TestRef;  import java.lang.ref.PhantomReference; import java.lang.ref.ReferenceQueue; import java.lang.ref.SoftReference; import java.lang.ref.WeakReference; import java.util.Map; import java.util.WeakHashMap;  public class Ref {     public Ref() {     }     /**      * @param args      */     public static void main(String[] args) {         try { //            test1(); //            test2(); //            test3(); //            test4(); //            test5();             test6();         } catch (InterruptedException e) {             // TODO Auto-generated catch block             e.printStackTrace();         }     }     /** 強(qiáng)引用,JVM的默認(rèn)實(shí)現(xiàn) */       public static void test1() throws InterruptedException {           Object obj = new Object();           Object strong = obj;           obj = null;           System.gc();           Thread.sleep(1000);           System.out.println("strong="+strong);     }       /**       * WeakReference 弱引用( 當(dāng)所引用的對(duì)象在 JVM 內(nèi)不再有強(qiáng)引用時(shí), GC 后weak reference 將會(huì)被自動(dòng)回收)       * */       public static void test2() throws InterruptedException {           Object obj = new Object();           WeakReference<Object> wr = new WeakReference<Object>(obj);           obj = null;           System.gc();           Thread.sleep(1000);           System.out.println("wr.get()="+wr.get());           System.out.println("wr="+wr);           wr.clear();         System.out.println("w1111r="+wr.get());       }       /**       * SoftReference SoftReference 于 WeakReference 的特性基本一致, ***的區(qū)別在于       * SoftReference 會(huì)盡可能長(zhǎng)的保留引用直到 JVM 內(nèi)存不足時(shí)才會(huì)被回收(虛擬機(jī)保證)       * */       public static void test3() throws InterruptedException {           Object obj = new Object();           SoftReference<Object> sr = new SoftReference<Object>(obj);           obj = null;           System.gc();           Thread.sleep(1000);           System.out.println("sr.get()="+sr.get());       }       /**       * PhantomReference Phantom Reference(幽靈引用) 與 WeakReference 和 SoftReference       * 有很大的不同, 因?yàn)樗?nbsp;get() 方法永遠(yuǎn)返回 null       * */       public static void test4() throws InterruptedException {           Object obj = new Object();           ReferenceQueue<Object> rq = new ReferenceQueue<Object>();           PhantomReference<Object> pr = new PhantomReference<Object>(obj, rq);           System.out.println("pr.get()="+pr.get());      }       /**      * ReferenceQueue:      * @throws InterruptedException      */     public static void test5() throws InterruptedException {           Object obj = new Object();           ReferenceQueue<Object> rq = new ReferenceQueue<Object>();           WeakReference<Object> pr = new WeakReference<Object>(obj, rq);           System.out.println("**pr.enqueue()="+pr.enqueue());           System.out.println("**pr.isEnqueued()="+pr.isEnqueued());               System.out.println("**pr="+pr);         System.out.println("**rq.poll()="+rq.poll());           obj = null;           System.gc();   //        System.out.println("pr.enqueue()="+pr.enqueue());   //        System.out.println("**pr.isEnqueued()="+pr.isEnqueued());       //        System.out.println("pr="+pr); //        System.out.println("rq.poll()="+rq.poll());   //        System.out.println("obj5="+obj);       }            /**       * 使用 WeakReference 作為 key, 一旦沒(méi)有指向 key 的強(qiáng)引用,        * WeakHashMap 在 GC 后將自動(dòng)刪除相關(guān)的       * entry       */       public static void test6() throws InterruptedException {           Map<Object, Object> map = new WeakHashMap<Object, Object>();           Object key = new Object();           Object value = new Object();           map.put(key, value);           key = null;   //        System.out.println("value="+value);   //        System.out.println("key="+key);   //        System.out.println("map.containsValue(value)="+map.containsValue(value));  //        System.out.println("map="+map);           System.gc();           Thread.sleep(1000);           System.out.println("value="+value);           System.out.println("key="+key);           System.out.println("map.containsValue(value)="+map.containsValue(value));          System.out.println("map="+map);       }   }

感謝各位的閱讀,以上就是“Java常見(jiàn)的四種引用是什么”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)Java常見(jiàn)的四種引用是什么這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

本文標(biāo)題:Java常見(jiàn)的四種引用是什么
URL鏈接:http://bm7419.com/article2/gihcoc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站排名App設(shè)計(jì)、響應(yīng)式網(wǎng)站、網(wǎng)站營(yíng)銷、Google、網(wǎng)站制作

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站網(wǎng)頁(yè)設(shè)計(jì)