国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - 全面解析Java中的GC與幽靈引用

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

2019-10-14 13:58java開發網 Java教程

一般的應用程序不會涉及到 Reference 編程, 但是了解這些知識會對理解 GC 的工作原理以及性能調優有一定幫助,在實現一些基礎性設施比如緩存時也可能會用到,希望本文能有所幫助

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

1、 Strong Reference
StrongReference 是 Java 的默認引用實現,  它會盡可能長時間的存活于 JVM 內, 當沒有任何對象指向它時 GC 執行后將會被回收

Java代碼 

復制代碼代碼如下:

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

    /** 
     * 通過賦值創建 StrongReference  
     */  
    Object strongReference = referent;  

    assertSame(referent, strongReference);  

    referent = null;  
    System.gc();  

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


2、 WeakReference & WeakHashMap
WeakReference, 顧名思義,  是一個弱引用,  當所引用的對象在 JVM 內不再有強引用時, GC 后 weak reference 將會被自動回收

復制代碼代碼如下:

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

    assertSame(referent, weakRerference.get());  

    referent = null;  
    System.gc();  

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


WeakHashMap 使用 WeakReference 作為 key, 一旦沒有指向 key 的強引用, WeakHashMap 在 GC 后將自動刪除相關的 entry

復制代碼代碼如下:

@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 進入 ReferenceQueue 以便下一次調用 getTable 時被清理 
     */  
    Thread.sleep(1000);  

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


3、SoftReference
SoftReference 于 WeakReference 的特性基本一致, 最大的區別在于 SoftReference 會盡可能長的保留引用直到 JVM 內存不足時才會被回收(虛擬機保證), 這一特性使得 SoftReference 非常適合緩存應用

復制代碼代碼如下:

@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 之前才會被回收, 所以它非常適合緩存應用 
     */  
    assertNotNull(softRerference.get());  
}  


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

 

Java代碼 

復制代碼代碼如下:

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

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


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

 

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

Java代碼 

復制代碼代碼如下:

@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  有兩個好處, 其一, 它可以讓我們準確地知道對象何時被從內存中刪除, 這個特性可以被用于一些特殊的需求中(例如 Distributed GC,  XWork 和 google-guice 中也使用 PhantomReference 做了一些清理性工作).

 

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

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

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. 小結
一般的應用程序不會涉及到 Reference 編程, 但是了解這些知識會對理解 GC 的工作原理以及性能調優有一定幫助,在實現一些基礎性設施比如緩存時也可能會用到, 希望本文能有所幫助。

延伸 · 閱讀

精彩推薦
  • Java教程JAVA中通過自定義注解進行數據驗證的方法

    JAVA中通過自定義注解進行數據驗證的方法

    java 自定義注解驗證可自己添加所需要的注解,下面這篇文章主要給大家介紹了關于JAVA中通過自定義注解進行數據驗證的相關資料,文中通過示例代碼介紹...

    Decouple6362021-05-25
  • Java教程JavaWeb 實現驗證碼功能(demo)

    JavaWeb 實現驗證碼功能(demo)

    在 WEB-APP 中一般應用于:登錄、注冊、買某票、秒殺等場景,大家都接觸過這個驗證碼操作,今天小編通過實例代碼給大家講解javaweb實現驗證碼功能,需要...

    java教程網12832020-08-05
  • Java教程Java list.remove( )方法注意事項

    Java list.remove( )方法注意事項

    這篇文章主要介紹了Java list.remove( )方法注意事項,非常簡單易懂,需要的朋友可以參考下...

    妖久9552021-05-25
  • Java教程SpringBoot引入Thymeleaf的實現方法

    SpringBoot引入Thymeleaf的實現方法

    這篇文章主要介紹了SpringBoot引入Thymeleaf的實現方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下...

    Bobby6472021-07-28
  • Java教程springboot ehcache 配置使用方法代碼詳解

    springboot ehcache 配置使用方法代碼詳解

    EhCache是一個比較成熟的Java緩存框架,Springboot對ehcache的使用非常支持,所以在Springboot中只需做些配置就可使用,且使用方式也簡易,今天給大家分享spri...

    m1719309529412912021-09-16
  • Java教程Java之Springcloud Feign組件詳解

    Java之Springcloud Feign組件詳解

    這篇文章主要介紹了Java之Springcloud Feign組件詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下...

    深情以改10322021-11-12
  • Java教程淺談Java(SpringBoot)基于zookeeper的分布式鎖實現

    淺談Java(SpringBoot)基于zookeeper的分布式鎖實現

    這篇文章主要介紹了Java(SpringBoot)基于zookeeper的分布式鎖實現,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的...

    LJY_SUPER5742021-07-21
  • Java教程java 中鎖的性能提高辦法

    java 中鎖的性能提高辦法

    這篇文章主要介紹了java 中鎖的性能提高辦法的相關資料,需要的朋友可以參考下...

    Java之家3092020-08-13
主站蜘蛛池模板: 亚洲国产中文字幕在线 | av在线电影网 | 黄色一级小视频 | 亚洲免费视频网 | 日韩在线免费视频 | 精品国产子伦久久久久久小说 | 精品久久伊人 | 伦乱视频| 欧美国产日韩在线 | www.国产.com | 一级性色 | 国产精品久久久久国产a级 成人a在线视频 | 欧美成人a∨高清免费观看 国产99久久 | 自拍偷拍第一页 | 一级毛片免费视频 | 伊人www22综合色 | 亚洲精品一区在线观看 | 亚洲三级视频 | 一区视频网站 | 中文字幕综合 | 色综合色综合网色综合 | 日韩国产欧美 | 亚洲天堂电影 | 久久国产精品久久久久久电车 | 亚洲精品一二三 | 99色综合 | 日韩成人精品 | 国产精品久久久久久久久久免费看 | 精品在线91 | 国产精品视频一区二区三区四 | 亚洲精品久久久久久一区二区 | 国产精品99久久久久久宅男 | 色aaaa| 成人精品动漫一区二区三区 | 成人免费在线小视频 | 日韩中文一区二区三区 | 一级黄色录像在线观看 | 国产精品久久久久久久久久久久久 | 色av中文字幕 | 999久久久国产999久久久 | 一本一本久久a久久精品综合妖精 |