最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java 中 Reference用法詳解

 更新時間:2017年03月15日 15:50:57   投稿:lqh  
這篇文章主要介紹了Java 中 Reference用法詳解的相關資料,需要的朋友可以參考下

Java  Reference詳解

在 jdk 1.2 及其以后,引入了強引用、軟引用、弱引用、虛引用這四個概念。網(wǎng)上很多關于這四個概念的解釋,但大多是概念性的泛泛而談,今天我結合著代碼分析了一下,首先我們先來看定義與大概解釋(引用類型在包 Java.lang.ref 里)。

  1、強引用(StrongReference)

    強引用不會被GC回收,并且在java.lang.ref里也沒有實際的對應類型。舉個例子來說:   

 Object obj = new Object();

    這里的obj引用便是一個強引用,不會被GC回收。

  2、軟引用(SoftReference)

    軟引用在JVM報告內(nèi)存不足的時候才會被GC回收,否則不會回收,正是由于這種特性軟引用在caching和pooling中用處廣泛。軟引用的用法:

Object obj = new Object();
SoftReference<Object> softRef = new SoftReference(obj);
// 使用 softRef.get() 獲取軟引用所引用的對象
Object objg = softRef.get();

  3、弱引用(WeakReference)

    當GC一但發(fā)現(xiàn)了弱引用對象,將會釋放WeakReference所引用的對象。弱引用使用方法與軟引用類似,但回收策略不同。

  4、虛引用(PhantomReference)

    當GC一但發(fā)現(xiàn)了虛引用對象,將會將PhantomReference對象插入ReferenceQueue隊列,而此時PhantomReference所指向的對象并沒有被GC回收,而是要等到ReferenceQueue被你真正的處理后才會被回收。虛引用的用法:

Object obj = new Object();
ReferenceQueue<Object> refQueue = new ReferenceQueue<Object>();
PhantomReference<Object> phanRef = new PhantomReference<Object>(obj, refQueue);
// 調(diào)用phanRef.get()不管在什么情況下會一直返回null
Object objg = phanRef.get();
// 如果obj被置為null,當GC發(fā)現(xiàn)了虛引用,GC會將phanRef插入進我們之前創(chuàng)建時傳入的refQueue隊列
// 注意,此時phanRef所引用的obj對象,并沒有被GC回收,在我們顯式地調(diào)用refQueue.poll返回phanRef之后
// 當GC第二次發(fā)現(xiàn)虛引用,而此時JVM將phanRef插入到refQueue會插入失敗,此時GC才會對obj進行回收
Reference<? extends Object> phanRefP = refQueue.poll();

看了簡單的定義之后,我們結合著代碼來測試一下,強引用就不用說了,軟引用的描述也很清楚,關鍵是 “弱引用” 與 “虛引用”。

弱引用:

public static void main(String[] args) throws InterruptedException {
  Object obj = new Object();
  ReferenceQueue<Object> refQueue = new ReferenceQueue<Object>();
  WeakReference<Object> weakRef = new WeakReference<Object>(obj, refQueue);
  System.out.println(weakRef.get());
  System.out.println(refQueue.poll());
  obj = null;
  System.gc();
  System.out.println(weakRef.get());
  System.out.println(refQueue.poll());
}

由于System.gc()是告訴JVM這是一個執(zhí)行GC的好時機,但具體執(zhí)不執(zhí)行由JVM決定,因此當JVM決定執(zhí)行GC,得到的結果便是(事實上這段代碼一般都會執(zhí)行GC):

  java.lang.Object@de6ced
  null
  null
  java.lang.ref.WeakReference@1fb8ee3

從執(zhí)行結果得知,通過調(diào)用weakRef.get()我們得到了obj對象,由于沒有執(zhí)行GC,因此refQueue.poll()返回的null,當我們把obj = null;此時沒有引用指向堆中的obj對象了,這里JVM執(zhí)行了一次GC,我們通過weakRef.get()發(fā)現(xiàn)返回了null,而refQueue.poll()返回了WeakReference對象,因此JVM在對obj進行了回收之后,才將weakRef插入到refQueue隊列中。

虛引用:

public static void main(String[] args) throws InterruptedException {
  Object obj = new Object();
  ReferenceQueue<Object> refQueue = new ReferenceQueue<Object>();
  PhantomReference<Object> phanRef = new PhantomReference<Object>(obj, refQueue);
  System.out.println(phanRef.get());
  System.out.println(refQueue.poll());
  obj = null;
  System.gc();
  System.out.println(phanRef.get());
  System.out.println(refQueue.poll());
}

同樣,當JVM執(zhí)行了GC,得到的結果便是:

  null
  null
  null
  java.lang.ref.PhantomReference@1fb8ee3

從執(zhí)行結果得知,我們先前說的沒有錯,phanRef.get()不管在什么情況下,都會返回null,而當JVM執(zhí)行GC發(fā)現(xiàn)虛引用之后,JVM并沒有回收obj,而是將PhantomReference對象插入到對應的虛引用隊列refQueue中,當調(diào)用refQueue.poll()返回PhantomReference對象時,poll方法會先把PhantomReference的持有隊列queue(ReferenceQueue<? super T>)置為NULL,NULL對象繼承自ReferenceQueue,將enqueue(Reference paramReference)方法覆蓋為return false,而此時obj再次被GC發(fā)現(xiàn)時,JVM再將PhantomReference插入到NULL隊列中便會插入失敗返回false,此時GC便會回收obj。事實上通過這段代碼我們也的卻看不出來obj是否被回收,但通過 PhantomReference 的javadoc注釋中有一句是這樣寫的:

Once the garbage collector decides that an object obj is phantom-reachable, it is being enqueued on the corresponding queue, but its referent is not cleared. That is, the reference queue of the phantom reference must explicitly be processed by some application code.

翻譯一下(這句話很簡單,我相信很多人應該也看得懂):

一旦GC決定一個“obj”是虛可達的,它(指PhantomReference)將會被入隊到對應的隊列,但是它的指代并沒有被清除。也就是說,虛引用的引用隊列一定要明確地被一些應用程序代碼所處理。

弱引用與虛引用的用處

  軟引用很明顯可以用來制作caching和pooling,而弱引用與虛引用呢?其實用處也很大,首先我們來看看弱引用,舉個例子:

class Registry {
  private Set registeredObjects = new HashSet();
 
  public void register(Object object) {
    registeredObjects.add( object );
  }
}

所有我添加進 registeredObjects 中的object永遠不會被GC回收,因為這里有個強引用保存在registeredObjects里,另一方面如果我把代碼改為如下:

class Registry {
   private Set registeredObjects = new HashSet();
 
   public void register(Object object) {
     registeredObjects.add( new WeakReference(object) );
   }
 }

  現(xiàn)在如果GC想要回收registeredObjects中的object,便能夠?qū)崿F(xiàn)了,同樣在使用HashMap如果想實現(xiàn)如上的效果,一種更好的實現(xiàn)是使用WeakHashMap。

而虛引用呢?我們先來看看javadoc的部分說明:

Phantom references are useful for implementing cleanup operations that are necessary before an object gets garbage-collected. They are sometimes more flexible than the finalize() method.

翻譯一下:

虛引用在實現(xiàn)一個對象被回收之前必須做清理操作是很有用的。有時候,他們比finalize()方法更靈活。

很明顯的,虛引用可以用來做對象被回收之前的清理工作。

 感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

相關文章

  • spring @Validated 注解開發(fā)中使用group分組校驗的實現(xiàn)

    spring @Validated 注解開發(fā)中使用group分組校驗的實現(xiàn)

    這篇文章主要介紹了spring @Validated 注解開發(fā)中使用group分組校驗的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-05-05
  • MacOS如何安裝配置多個JDK并切換使用詳解

    MacOS如何安裝配置多個JDK并切換使用詳解

    這篇文章主要介紹了如何在MacOS上安裝和配置多個JDK版本,通過配置環(huán)境變量來實現(xiàn),文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2025-02-02
  • Spring中Bean注入源碼示例解析

    Spring中Bean注入源碼示例解析

    這篇文章主要為大家介紹了Spring中Bean注入源碼示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-01-01
  • SpringBoot整合Spring?Security過濾器鏈加載執(zhí)行流程源碼分析(最新推薦)

    SpringBoot整合Spring?Security過濾器鏈加載執(zhí)行流程源碼分析(最新推薦)

    Spring?Boot?對于?Spring?Security?提供了自動化配置方案,可以使用更少的配置來使用?Spring?Security,這篇文章主要介紹了SpringBoot整合Spring?Security過濾器鏈加載執(zhí)行流程源碼分析,需要的朋友可以參考下
    2023-02-02
  • MyBatis傳入List集合查詢數(shù)據(jù)問題

    MyBatis傳入List集合查詢數(shù)據(jù)問題

    這篇文章主要介紹了MyBatis傳入List集合查詢數(shù)據(jù)問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • Java 網(wǎng)絡爬蟲新手入門詳解

    Java 網(wǎng)絡爬蟲新手入門詳解

    這篇文章主要介紹了Java 網(wǎng)絡爬蟲新手入門詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-10-10
  • Spring Boot 通過 Mvc 擴展方便進行貨幣單位轉(zhuǎn)換的代碼詳解

    Spring Boot 通過 Mvc 擴展方便進行貨幣單位轉(zhuǎn)換的代碼詳解

    這篇文章主要介紹了Spring Boot 通過 Mvc 擴展方便進行貨幣單位轉(zhuǎn)換,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-12-12
  • Java基礎教程之String深度分析

    Java基礎教程之String深度分析

    這篇文章主要給大家介紹了關于Java基礎教程之String的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-06-06
  • 如何區(qū)分JAVA中的equals與==

    如何區(qū)分JAVA中的equals與==

    這篇文章主要介紹了如何區(qū)分JAVA中的equals與==,文章簡單易懂,實例代碼幫助大家更好的參考學習,感興趣的朋友可以了解下
    2020-06-06
  • Java開發(fā)如何把數(shù)據(jù)庫里的未付款訂單改成已付款

    Java開發(fā)如何把數(shù)據(jù)庫里的未付款訂單改成已付款

    這篇文章主要介紹了Java開發(fā)如何把數(shù)據(jù)庫里的未付款訂單改成已付款,先介紹MD5算法,簡單的來說,MD5能把任意大小、長度的數(shù)據(jù)轉(zhuǎn)換成固定長度的一串字符,實現(xiàn)思路非常簡單需要的朋友可以參考下
    2022-11-11

最新評論

中西区| 呼和浩特市| 连云港市| 景洪市| 顺昌县| 历史| 绍兴市| 丹东市| 安平县| 永靖县| 广州市| 清水县| 余干县| 阿尔山市| 贵定县| 来宾市| 德保县| 福建省| 兰坪| 曲靖市| 龙口市| 北票市| 峨眉山市| 铜川市| 榆社县| 芒康县| 长兴县| 阳曲县| 佛山市| 和田县| 大同县| 沈丘县| 屏东县| 安康市| 凉山| 靖边县| 永济市| 涞水县| 吴堡县| 儋州市| 商城县|