亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Java > 正文

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

2019-11-26 15:58:17
字體:
來源:轉載
供稿:網友

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
TypePurposeUseWhen GCedImplementing Class
Strong ReferenceAn ordinary reference. Keeps objects alive as long as they are referenced.normal reference.Any object not pointed to can be reclaimed.default
Soft ReferenceKeeps 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 ReferenceKeeps 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 reachablejava.lang.ref.WeakReference 
java.util.WeakHashMap
Phantom ReferenceLets you clean up after finalization but before the space is reclaimed (replaces or augments the use offinalize())Special clean up processingAfter finalization.java.lang.ref.PhantomReference

 

 

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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品69精品一区二区三区| 亚洲国产另类 国产精品国产免费| 久久免费精品日本久久中文字幕| 欧美xxxx做受欧美.88| 日韩在线欧美在线| 欧美日韩亚洲一区二| 欧美日韩国产精品一区二区三区四区| 韩国日本不卡在线| 午夜精品免费视频| 日韩美女视频在线观看| 国产成人精品一区二区三区| 国产精品91久久久久久| 日本久久中文字幕| 久久久久久国产三级电影| 久久久久999| 国产精品视频最多的网站| 日本成人免费在线| 亚洲第一区在线观看| 国产精品va在线播放我和闺蜜| 日韩精品丝袜在线| 国内精品久久久久| 国产成人精品视频在线观看| 亚洲区在线播放| 欧美日韩国产丝袜美女| 久久99精品视频一区97| 日本高清不卡的在线| 热久久免费视频精品| 日韩国产在线看| 国产精品自产拍在线观看| www欧美日韩| 日韩av快播网址| 日韩高清不卡av| 亚洲a在线播放| 欧美在线视频在线播放完整版免费观看| 久久久久国产精品一区| 日韩久久免费视频| 亚洲自拍高清视频网站| 日韩成人性视频| 亚洲精品美女在线观看| 亚洲区免费影片| 91社影院在线观看| 热久久这里只有精品| 91国自产精品中文字幕亚洲| 国产午夜精品全部视频在线播放| 久久99国产精品自在自在app| 日韩欧美在线视频日韩欧美在线视频| 欧美富婆性猛交| 成人免费观看49www在线观看| 欧美激情亚洲一区| 最新的欧美黄色| 精品亚洲男同gayvideo网站| 最近2019免费中文字幕视频三| 欧美色图在线视频| 欧美精品在线观看| 亚洲精品v欧美精品v日韩精品| 日韩成人激情在线| 欧美一级免费看| 96国产粉嫩美女| 成人有码在线视频| 日韩免费观看在线观看| 国产精品久久久久久久久粉嫩av| 久久99亚洲精品| 亚洲va国产va天堂va久久| 日韩精品在线视频观看| 国产日韩精品在线观看| 日韩精品视频中文在线观看| 国产精自产拍久久久久久蜜| 亚洲精品视频二区| 丝袜美腿亚洲一区二区| 超碰97人人做人人爱少妇| 国产有码在线一区二区视频| 欧美激情第一页xxx| 亚洲黄一区二区| 国产成人精品视频| 精品小视频在线| 欧美亚洲日本黄色| 这里只有精品视频| 国产丝袜一区二区| 亚洲精品在线观看www| 97久久精品人人澡人人爽缅北| 欧美在线日韩在线| 精品久久久久久久久中文字幕| 色樱桃影院亚洲精品影院| 国产精品对白刺激| 日韩亚洲欧美中文高清在线| 国产一区二区三区直播精品电影| 亚洲网站在线播放| 欧美激情视频一区二区三区不卡| 日韩欧美黄色动漫| 日韩在线视频网| 国产精品成人v| 亚洲跨种族黑人xxx| 欧美电影免费观看高清| 成人在线中文字幕| 久久久久久国产精品美女| 中文字幕亚洲综合久久筱田步美| 亚洲专区在线视频| 久久免费视频这里只有精品| 日韩免费视频在线观看| 欧美日韩国产精品一区| 久久国产精品免费视频| 成人免费网站在线| 欧美性视频精品| 日韩精品视频中文在线观看| 色久欧美在线视频观看| 懂色aⅴ精品一区二区三区蜜月| 成人亚洲激情网| 久久久久久久国产精品视频| 欧美激情精品久久久久久免费印度| 精品一区二区电影| 欧美巨乳美女视频| 久久久久久国产免费| 91免费高清视频| 91精品国产91久久久久久不卡| 久久国产精品亚洲| 成人免费网视频| 日韩一区二区福利| 国产精品扒开腿做爽爽爽视频| 一本色道久久综合狠狠躁篇怎么玩| 成人国产精品久久久久久亚洲| 欧美性理论片在线观看片免费| 亚洲女人天堂视频| 日本国产精品视频| www.99久久热国产日韩欧美.com| www.xxxx欧美| 国产精品久久久久久av下载红粉| 国内外成人免费激情在线视频| 亚洲精品网站在线播放gif| 国产精品免费福利| 国产精品夜色7777狼人| 亚洲一区二区黄| 国产精品中文字幕久久久| 91av网站在线播放| 亚洲第一福利在线观看| 国产精品成人久久久久| 国产99视频在线观看| 中文字幕免费精品一区| 91丝袜美腿美女视频网站| 欧美日韩裸体免费视频| 日韩电影中文字幕av| 欧美成人精品不卡视频在线观看| 欧美国产日本在线| 欧美日韩中文字幕在线视频| 国产亚洲一区二区精品| 日韩国产一区三区| 青草青草久热精品视频在线网站| 久久综合伊人77777| 欧美一区二区三区免费视| 国产精品中文久久久久久久| 色爱av美腿丝袜综合粉嫩av| 久久男人av资源网站| 欧美激情第一页xxx| 久久免费视频网站| 成人美女免费网站视频| 亚洲天堂一区二区三区| 国产精品pans私拍| 国产精品入口福利| 日韩成人久久久| 欧美日韩午夜激情| 中文字幕亚洲综合久久筱田步美| 亚洲字幕在线观看| 国产成人午夜视频网址| 国产精品福利片| 疯狂做受xxxx欧美肥白少妇|