激情久久久_欧美视频区_成人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 的工作原理以及性能調優有一定幫助,在實現一些基礎性設施比如緩存時也可能會用到, 希望本文能有所幫助。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 中国a级黄色片 | 国产成人自拍小视频 | 欧美高清一级片 | 999久久国产 | 羞羞网站在线看 | 福利免费视频 | 国产亚洲精品久久久久久久久 | 国产精品v片在线观看不卡 国产另类一区 | www亚洲成人| 免费永久看羞羞片网站入口 | 国产亚洲精品久久久闺蜜 | 一区二区国产在线 | 成人羞羞视频在线观看免费 | 久久久久久久久久久国产精品 | 羞羞的视频在线 | 一区二区三区四区免费看 | 中文字幕欧美专区 | 亚洲午夜免费 | 中文字幕免费播放 | 性爱视频在线免费 | 一区小视频 | 国产www免费| 一级做受大片免费视频 | 最新福利在线 | 午夜国内精品a一区二区桃色 | 九草网| 久久久久久久久久久久久久av | 99热99精品 | 激情在线免费观看 | 激情九九 | 午夜小视频免费观看 | 欧美亚洲一区二区三区四区 | 伊人一二三四区 | 国产在线1区 | 日本中文视频 | 久久久成人一区二区免费影院 | 毛片视频网址 | 日韩av一二三区 | 欧洲精品久久 | 国产午夜精品理论片a级探花 | 国产一国产精品一级毛片 |