亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

全面解析Java中的GC與幽靈引用

 更新時間:2013年09月11日 10:05:22   作者:  
一般的應(yīng)用程序不會涉及到 Reference 編程, 但是了解這些知識會對理解 GC 的工作原理以及性能調(diào)優(yōu)有一定幫助,在實現(xiàn)一些基礎(chǔ)性設(shè)施比如緩存時也可能會用到,希望本文能有所幫助

Java 中一共有 4 種類型的引用 : StrongReference、 SoftReference、 WeakReference 以及 PhantomReference (傳說中的幽靈引用 呵呵),
這 4 種類型的引用與 GC 有著密切的關(guān)系,  讓我們逐一來看它們的定義和使用場景 :

1、 Strong Reference
StrongReference 是 Java 的默認(rèn)引用實現(xiàn),  它會盡可能長時間的存活于 JVM 內(nèi), 當(dāng)沒有任何對象指向它時 GC 執(zhí)行后將會被回收

Java代碼

復(fù)制代碼 代碼如下:

@Test 
public void strongReference() { 
    Object referent = new Object(); 

    /**
     * 通過賦值創(chuàng)建 StrongReference 
     */ 
    Object strongReference = referent; 

    assertSame(referent, strongReference); 

    referent = null; 
    System.gc(); 

    /**
     * StrongReference 在 GC 后不會被回收
     */ 
    assertNotNull(strongReference); 


2、 WeakReference & WeakHashMap
WeakReference, 顧名思義,  是一個弱引用,  當(dāng)所引用的對象在 JVM 內(nèi)不再有強(qiáng)引用時, GC 后 weak reference 將會被自動回收
復(fù)制代碼 代碼如下:

@Test 
public void weakReference() { 
    Object referent = new Object(); 
    WeakReference<Object> weakRerference = new WeakReference<Object>(referent); 

    assertSame(referent, weakRerference.get()); 

    referent = null; 
    System.gc(); 

    /**
     * 一旦沒有指向 referent 的強(qiáng)引用, weak reference 在 GC 后會被自動回收
     */ 
    assertNull(weakRerference.get()); 


WeakHashMap 使用 WeakReference 作為 key, 一旦沒有指向 key 的強(qiáng)引用, WeakHashMap 在 GC 后將自動刪除相關(guān)的 entry
復(fù)制代碼 代碼如下:

@Test 
public void weakHashMap() throws InterruptedException { 
    Map<Object, Object> weakHashMap = new WeakHashMap<Object, Object>(); 
    Object key = new Object(); 
    Object value = new Object(); 
    weakHashMap.put(key, value); 

    assertTrue(weakHashMap.containsValue(value)); 

    key = null; 
    System.gc(); 

    /**
     * 等待無效 entries 進(jìn)入 ReferenceQueue 以便下一次調(diào)用 getTable 時被清理
     */ 
    Thread.sleep(1000); 

    /**
     * 一旦沒有指向 key 的強(qiáng)引用, WeakHashMap 在 GC 后將自動刪除相關(guān)的 entry
     */ 
    assertFalse(weakHashMap.containsValue(value)); 


3、SoftReference
SoftReference 于 WeakReference 的特性基本一致, 最大的區(qū)別在于 SoftReference 會盡可能長的保留引用直到 JVM 內(nèi)存不足時才會被回收(虛擬機(jī)保證), 這一特性使得 SoftReference 非常適合緩存應(yīng)用
復(fù)制代碼 代碼如下:

@Test 
public void softReference() { 
    Object referent = new Object(); 
    SoftReference<Object> softRerference = new SoftReference<Object>(referent); 

    assertNotNull(softRerference.get()); 

    referent = null; 
    System.gc(); 

    /**
     *  soft references 只有在 jvm OutOfMemory 之前才會被回收, 所以它非常適合緩存應(yīng)用
     */ 
    assertNotNull(softRerference.get()); 


4、 PhantomReference
作為本文主角, Phantom Reference(幽靈引用) 與 WeakReference 和 SoftReference 有很大的不同,  因為它的 get() 方法永遠(yuǎn)返回 null, 這也正是它名字的由來

Java代碼

復(fù)制代碼 代碼如下:

@Test 
public void phantomReferenceAlwaysNull() { 
    Object referent = new Object(); 
    PhantomReference<Object> phantomReference = new PhantomReference<Object>(referent, new ReferenceQueue<Object>()); 

    /**
     * phantom reference 的 get 方法永遠(yuǎn)返回 null 
     */ 
    assertNull(phantomReference.get()); 


諸位可能要問, 一個永遠(yuǎn)返回 null 的 reference 要來何用,  請注意構(gòu)造 PhantomReference 時的第二個參數(shù) ReferenceQueue(事實上 WeakReference & SoftReference 也可以有這個參數(shù)),
PhantomReference 唯一的用處就是跟蹤 referent  何時被 enqueue 到 ReferenceQueue 中.

5、 RererenceQueue
當(dāng)一個 WeakReference 開始返回 null 時, 它所指向的對象已經(jīng)準(zhǔn)備被回收, 這時可以做一些合適的清理工作.   將一個 ReferenceQueue 傳給一個 Reference 的構(gòu)造函數(shù), 當(dāng)對象被回收時, 虛擬機(jī)會自動將這個對象插入到 ReferenceQueue 中, WeakHashMap 就是利用 ReferenceQueue 來清除 key 已經(jīng)沒有強(qiáng)引用的 entries.

Java代碼

復(fù)制代碼 代碼如下:

@Test 
public void referenceQueue() throws InterruptedException { 
    Object referent = new Object();      
    ReferenceQueue<Object> referenceQueue = new ReferenceQueue<Object>(); 
    WeakReference<Object> weakReference = new WeakReference<Object>(referent, referenceQueue); 

    assertFalse(weakReference.isEnqueued()); 
    Reference<? extends Object> polled = referenceQueue.poll(); 
    assertNull(polled); 

    referent = null; 
    System.gc(); 

    assertTrue(weakReference.isEnqueued()); 
    Reference<? extends Object> removed = referenceQueue.remove(); 
    assertNotNull(removed); 


6、PhantomReference  vs WeakReference
PhantomReference  有兩個好處, 其一, 它可以讓我們準(zhǔn)確地知道對象何時被從內(nèi)存中刪除, 這個特性可以被用于一些特殊的需求中(例如 Distributed GC,  XWork 和 google-guice 中也使用 PhantomReference 做了一些清理性工作).

其二, 它可以避免 finalization 帶來的一些根本性問題, 上文提到 PhantomReference 的唯一作用就是跟蹤 referent 何時被 enqueue 到 ReferenceQueue 中,  但是 WeakReference 也有對應(yīng)的功能, 兩者的區(qū)別到底在哪呢 ?

這就要說到 Object 的 finalize 方法, 此方法將在 gc 執(zhí)行前被調(diào)用, 如果某個對象重載了 finalize 方法并故意在方法內(nèi)創(chuàng)建本身的強(qiáng)引用,  這將導(dǎo)致這一輪的 GC 無法回收這個對象并有可能引起任意次 GC, 最后的結(jié)果就是明明 JVM 內(nèi)有很多 Garbage 卻 OutOfMemory, 使用 PhantomReference 就可以避免這個問題, 因為 PhantomReference 是在 finalize 方法執(zhí)行后回收的,也就意味著此時已經(jīng)不可能拿到原來的引用, 也就不會出現(xiàn)上述問題,  當(dāng)然這是一個很極端的例子, 一般不會出現(xiàn).

7、 對比

Soft vs Weak vs Phantom References
Type Purpose Use When GCed Implementing Class
Strong Reference An ordinary reference. Keeps objects alive as long as they are referenced. normal reference. Any object not pointed to can be reclaimed. default
Soft Reference Keeps objects alive provided there's enough memory. to keep objects alive even after clients have removed their references (memory-sensitive caches), in case clients start asking for them again by key. After a first gc pass, the JVM decides it still needs to reclaim more space. java.lang.ref.SoftReference
Weak Reference Keeps objects alive only while they're in use (reachable) by clients. Containers that automatically delete objects no longer in use. After gc determines the object is only weakly reachable java.lang.ref.WeakReference 
java.util.WeakHashMap
Phantom Reference Lets you clean up after finalization but before the space is reclaimed (replaces or augments the use offinalize()) Special clean up processing After finalization. java.lang.ref.PhantomReference

 

 

8. 小結(jié)
一般的應(yīng)用程序不會涉及到 Reference 編程, 但是了解這些知識會對理解 GC 的工作原理以及性能調(diào)優(yōu)有一定幫助,在實現(xiàn)一些基礎(chǔ)性設(shè)施比如緩存時也可能會用到, 希望本文能有所幫助。

相關(guān)文章

  • Springboot?手動分頁查詢分批批量插入數(shù)據(jù)的實現(xiàn)流程

    Springboot?手動分頁查詢分批批量插入數(shù)據(jù)的實現(xiàn)流程

    這篇文章主要介紹了Springboot?手動分頁查詢分批批量插入數(shù)據(jù)的實現(xiàn)流程,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-07-07
  • JavaWeb開發(fā)之模仿知乎首頁完整代碼

    JavaWeb開發(fā)之模仿知乎首頁完整代碼

    這篇文章主要介紹了JavaWeb開發(fā)之模仿知乎首頁完整代碼的相關(guān)資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2016-11-11
  • centos下GitLab+Jenkins持續(xù)集成環(huán)境搭建(安裝jenkins)

    centos下GitLab+Jenkins持續(xù)集成環(huán)境搭建(安裝jenkins)

    這篇文章主要為大家詳細(xì)介紹了centos下搭建GitLab+Jenkins持續(xù)集成環(huán)境,安裝jenkins的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • Java方法的覆蓋與隱藏的區(qū)別分析

    Java方法的覆蓋與隱藏的區(qū)別分析

    本篇文章介紹了,關(guān)于Java方法的覆蓋與隱藏的區(qū)別分析。需要的朋友參考下
    2013-04-04
  • Java中BeanUtils.copyProperties的11個坑總結(jié)

    Java中BeanUtils.copyProperties的11個坑總結(jié)

    我們?nèi)粘i_發(fā)中,經(jīng)常涉及到DO、DTO、VO對象屬性拷貝賦值,很容易想到org.springframework.beans.BeanUtils的copyProperties,它會自動通過反射機(jī)制獲取源對象和目標(biāo)對象的屬性,pyProperties,會有好幾個坑呢,本文將給大家總結(jié)一下遇到的坑,需要的朋友可以參考下
    2023-05-05
  • SpringBoot圖文并茂講解Lombok庫的安裝與使用

    SpringBoot圖文并茂講解Lombok庫的安裝與使用

    Lombok想要解決了的是在我們實體Bean中大量的Getter/Setter方法,以及toString, hashCode等可能不會用到,但是某些時候仍然需要復(fù)寫,以期方便使用的方法;在使用Lombok之后,將由其來自動幫你實現(xiàn)代碼生成
    2022-06-06
  • Java基于rest assured實現(xiàn)接口測試過程解析

    Java基于rest assured實現(xiàn)接口測試過程解析

    這篇文章主要介紹了Java基于rest assured實現(xiàn)接口測試過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-03-03
  • springboot啟動不了也不報錯的問題及解決

    springboot啟動不了也不報錯的問題及解決

    這篇文章主要介紹了springboot啟動不了也不報錯的問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • 淺談Mybatis傳參類型如何確定

    淺談Mybatis傳參類型如何確定

    最近有小伙伴在討論#{}與${}的區(qū)別時,有提到#{}是用字符串進(jìn)行替換,本文主要介紹了mapper接口中不同的參數(shù)類型,最終拼接sql中是如何進(jìn)行替換的,感興趣的可以了解一下
    2021-10-10
  • Java Socket聊天室編程(一)之利用socket實現(xiàn)聊天之消息推送

    Java Socket聊天室編程(一)之利用socket實現(xiàn)聊天之消息推送

    這篇文章主要介紹了Java Socket聊天室編程(一)之利用socket實現(xiàn)聊天之消息推送的相關(guān)資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2016-09-09

最新評論