欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java 中 Reference用法詳解

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

Java  Reference詳解

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

  1、強(qiáng)引用(StrongReference)

    強(qiáng)引用不會(huì)被GC回收,并且在java.lang.ref里也沒(méi)有實(shí)際的對(duì)應(yīng)類型。舉個(gè)例子來(lái)說(shuō):   

 Object obj = new Object();

    這里的obj引用便是一個(gè)強(qiáng)引用,不會(huì)被GC回收。

  2、軟引用(SoftReference)

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

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

  3、弱引用(WeakReference)

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

  4、虛引用(PhantomReference)

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

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

看了簡(jiǎn)單的定義之后,我們結(jié)合著代碼來(lái)測(cè)試一下,強(qiáng)引用就不用說(shuō)了,軟引用的描述也很清楚,關(guān)鍵是 “弱引用” 與 “虛引用”。

弱引用:

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這是一個(gè)執(zhí)行GC的好時(shí)機(jī),但具體執(zhí)不執(zhí)行由JVM決定,因此當(dāng)JVM決定執(zhí)行GC,得到的結(jié)果便是(事實(shí)上這段代碼一般都會(huì)執(zhí)行GC):

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

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

虛引用:

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());
}

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

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

從執(zhí)行結(jié)果得知,我們先前說(shuō)的沒(méi)有錯(cuò),phanRef.get()不管在什么情況下,都會(huì)返回null,而當(dāng)JVM執(zhí)行GC發(fā)現(xiàn)虛引用之后,JVM并沒(méi)有回收obj,而是將PhantomReference對(duì)象插入到對(duì)應(yīng)的虛引用隊(duì)列refQueue中,當(dāng)調(diào)用refQueue.poll()返回PhantomReference對(duì)象時(shí),poll方法會(huì)先把PhantomReference的持有隊(duì)列queue(ReferenceQueue<? super T>)置為NULL,NULL對(duì)象繼承自ReferenceQueue,將enqueue(Reference paramReference)方法覆蓋為return false,而此時(shí)obj再次被GC發(fā)現(xiàn)時(shí),JVM再將PhantomReference插入到NULL隊(duì)列中便會(huì)插入失敗返回false,此時(shí)GC便會(huì)回收obj。事實(shí)上通過(guò)這段代碼我們也的卻看不出來(lái)obj是否被回收,但通過(guò) 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.

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

一旦GC決定一個(gè)“obj”是虛可達(dá)的,它(指PhantomReference)將會(huì)被入隊(duì)到對(duì)應(yīng)的隊(duì)列,但是它的指代并沒(méi)有被清除。也就是說(shuō),虛引用的引用隊(duì)列一定要明確地被一些應(yīng)用程序代碼所處理。

弱引用與虛引用的用處

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

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

所有我添加進(jìn) registeredObjects 中的object永遠(yuǎn)不會(huì)被GC回收,因?yàn)檫@里有個(gè)強(qiáng)引用保存在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如果想實(shí)現(xiàn)如上的效果,一種更好的實(shí)現(xiàn)是使用WeakHashMap。

而虛引用呢?我們先來(lái)看看javadoc的部分說(shuō)明:

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.

翻譯一下:

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

很明顯的,虛引用可以用來(lái)做對(duì)象被回收之前的清理工作。

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

相關(guān)文章

  • Selenium Webdriver實(shí)現(xiàn)截圖功能的示例

    Selenium Webdriver實(shí)現(xiàn)截圖功能的示例

    今天小編就為大家分享一篇Selenium Webdriver實(shí)現(xiàn)截圖功能的示例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-05-05
  • Springmvc項(xiàng)目web.xml中servlet-mapping路徑映射配置注意說(shuō)明

    Springmvc項(xiàng)目web.xml中servlet-mapping路徑映射配置注意說(shuō)明

    這篇文章主要介紹了Springmvc項(xiàng)目web.xml中servlet-mapping路徑映射配置注意說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • 詳解使用IntelliJ IDEA 配置Maven(入門)

    詳解使用IntelliJ IDEA 配置Maven(入門)

    本篇文章主要介紹了詳解使用IntelliJ IDEA 配置Maven(入門),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-11-11
  • 如何解決@NotBlank不生效的問(wèn)題

    如何解決@NotBlank不生效的問(wèn)題

    這篇文章主要介紹了如何解決@NotBlank不生效的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Spring中的aware接口詳情

    Spring中的aware接口詳情

    這篇文章主要介紹了Spring中的aware接口詳情,Spring中有很多繼承于aware中的接口,這些接口到底是做什么用到的,下面我們就一起來(lái)看看吧,文章詳細(xì)內(nèi)容需要的小伙伴可以參考一下
    2022-05-05
  • Spring data jpa @Query update的坑及解決

    Spring data jpa @Query update的坑及解決

    這篇文章主要介紹了Spring data jpa @Query update的坑及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • SpringCloud使用Feign實(shí)現(xiàn)動(dòng)態(tài)路由操作

    SpringCloud使用Feign實(shí)現(xiàn)動(dòng)態(tài)路由操作

    這篇文章主要介紹了SpringCloud使用Feign實(shí)現(xiàn)動(dòng)態(tài)路由操作,文章圍繞主題展開詳細(xì)的內(nèi)容介紹具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-06-06
  • spring boot中的靜態(tài)資源加載處理方式

    spring boot中的靜態(tài)資源加載處理方式

    這篇文章主要介紹了spring boot中的靜態(tài)資源加載處理方式,需要的朋友可以參考下
    2017-04-04
  • Java集合之CopyOnWriteArrayList詳解

    Java集合之CopyOnWriteArrayList詳解

    這篇文章主要介紹了Java集合之CopyOnWriteArrayList詳解,CopyOnWriteArrayList是ArrayList的線程安全版本,內(nèi)部也是通過(guò)數(shù)組實(shí)現(xiàn),每次對(duì)數(shù)組的修改都完全拷貝一份新的數(shù)組來(lái)修改,修改完了再替換掉老數(shù)組,這樣保證了只阻塞寫操作,需要的朋友可以參考下
    2023-12-12
  • Java foreach循環(huán)的使用方法詳解

    Java foreach循環(huán)的使用方法詳解

    Java SE5引入了一種更加簡(jiǎn)潔的for語(yǔ)法用于數(shù)組和容器,即foreach語(yǔ)法,表示不必創(chuàng)建int變量去對(duì)由訪問(wèn)項(xiàng)構(gòu)成的序列進(jìn)行計(jì)數(shù),foreach將自動(dòng)產(chǎn)生每一項(xiàng),這種循環(huán)方式在我們后來(lái)遍歷集合時(shí)很常用,所以也有必要來(lái)學(xué)習(xí)一下,需要的朋友可以參考下
    2023-05-05

最新評(píng)論