成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

簡單理解Java GC與幽靈引用

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

1. Strong Reference

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

  1. @Test  
  2. public void strongReference() {   
  3. Object referent = new Object();   
  4.    
  5. /**  
  6.  * 通過賦值創建 StrongReference   
  7.  */  
  8. Object strongReference = referent;   
  9.    
  10. assertSame(referent, strongReference);   
  11.    
  12. referent = null;   
  13. System.gc();   
  14.    
  15. /**  
  16.  * StrongReference 在 GC 后不會被回收  
  17.  */  
  18. assertNotNull(strongReference);   
  19. }   
  20.  
  21.  @Test  
  22.  public void strongReference() {  
  23.   Object referent = new Object();  
  24.     
  25.   /**  
  26.    * 通過賦值創建 StrongReference   
  27.    */  
  28.   Object strongReference = referent;  
  29.     
  30.   assertSame(referent, strongReference);  
  31.     
  32.   referent = null;  
  33.   System.gc();  
  34.     
  35.   /**  
  36.    * StrongReference 在 GC 后不會被回收  
  37.    */  
  38.   assertNotNull(strongReference);  
  39.  } 

2. WeakReference & WeakHashMap

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

  1. @Test  
  2. public void weakReference() {   
  3. Object referent = new Object();   
  4. WeakReference<Object> weakRerference = new WeakReference<Object>(referent);   
  5.  
  6. assertSame(referent, weakRerference.get());   
  7.    
  8. referent = null;   
  9. System.gc();   
  10.    
  11. /**  
  12.  * 一旦沒有指向 referent 的強引用, weak reference 在 GC 后會被自動回收  
  13.  */  
  14. assertNull(weakRerference.get());   
  15. }   
  16.  
  17.  @Test  
  18.  public void weakReference() {  
  19.   Object referent = new Object();  
  20.   WeakReference<Object> weakRerference = new WeakReference<Object>(referent);  
  21.    
  22.   assertSame(referent, weakRerference.get());  
  23.     
  24.   referent = null;  
  25.   System.gc();  
  26.     
  27.   /**  
  28.    * 一旦沒有指向 referent 的強引用, weak reference 在 GC 后會被自動回收  
  29.    */  
  30.   assertNull(weakRerference.get());  
  31.  } 

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

  1. @Test  
  2. public void weakHashMap() throws InterruptedException {   
  3. Map<Object, Object> weakHashMap = new WeakHashMap<Object, Object>();   
  4. Object key = new Object();   
  5. Object value = new Object();   
  6. weakHashMap.put(key, value);   
  7.  
  8. assertTrue(weakHashMap.containsValue(value));   
  9.    
  10. key = null;   
  11. System.gc();   
  12.    
  13. /**  
  14.  * 等待無效 entries 進入 ReferenceQueue 以便下一次調用 getTable 時被清理  
  15.  */  
  16. Thread.sleep(1000);   
  17.    
  18. /**  
  19.  * 一旦沒有指向 key 的強引用, WeakHashMap 在 GC 后將自動刪除相關的 entry  
  20.  */  
  21. assertFalse(weakHashMap.containsValue(value));   
  22. }   
  23.  
  24.  @Test  
  25.  public void weakHashMap() throws InterruptedException {  
  26.   Map<Object, Object> weakHashMap = new WeakHashMap<Object, Object>();  
  27.   Object key = new Object();  
  28.   Object value = new Object();  
  29.   weakHashMap.put(key, value);  
  30.    
  31.   assertTrue(weakHashMap.containsValue(value));  
  32.     
  33.   key = null;  
  34.   System.gc();  
  35.     
  36.   /**  
  37.    * 等待無效 entries 進入 ReferenceQueue 以便下一次調用 getTable 時被清理  
  38.    */  
  39.   Thread.sleep(1000);  
  40.     
  41.   /**  
  42.    * 一旦沒有指向 key 的強引用, WeakHashMap 在 GC 后將自動刪除相關的 entry  
  43.    */  
  44.   assertFalse(weakHashMap.containsValue(value));  
  45.  } 

 3. SoftReference

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

  1. @Test  
  2. public void softReference() {   
  3. Object referent = new Object();   
  4. SoftReference<Object> softRerference = new SoftReference<Object>(referent);   
  5.  
  6. assertNotNull(softRerference.get());   
  7.    
  8. referent = null;   
  9. System.gc();   
  10.    
  11. /**  
  12.  *soft references 只有在 jvm OutOfMemory 之前才會被回收, 所以它非常適合緩存應用  
  13.  */  
  14. assertNotNull(softRerference.get());   
  15. }   
  16.  
  17.  @Test  
  18.  public void softReference() {  
  19.   Object referent = new Object();  
  20.   SoftReference<Object> softRerference = new SoftReference<Object>(referent);  
  21.    
  22.   assertNotNull(softRerference.get());  
  23.     
  24.   referent = null;  
  25.   System.gc();  
  26.     
  27.   /**  
  28.    *soft references 只有在 jvm OutOfMemory 之前才會被回收, 所以它非常適合緩存應用  
  29.    */  
  30.   assertNotNull(softRerference.get());  
  31.  } 

4. PhantomReference

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

  1. @Test  
  2. public void phantomReferenceAlwaysNull() {   
  3. Object referent = new Object();   
  4. PhantomReference<Object> phantomReference = new PhantomReference<Object>(referent, new ReferenceQueue<Object>());   
  5.    
  6. /**  
  7.  * phantom reference 的 get 方法永遠返回 null   
  8.  */  
  9. assertNull(phantomReference.get());   
  10. }   
  11.  
  12.  @Test  
  13.  public void phantomReferenceAlwaysNull() {  
  14.   Object referent = new Object();  
  15.   PhantomReference<Object> phantomReference = new PhantomReference<Object>(referent, new ReferenceQueue<Object>());  
  16.     
  17.   /**  
  18.    * phantom reference 的 get 方法永遠返回 null   
  19.    */  
  20.   assertNull(phantomReference.get());  
  21.  } 

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

5. RererenceQueue

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

  1. @Test  
  2. public void referenceQueue() throws InterruptedException {   
  3. Object referent = new Object();  
  4. ReferenceQueue<Object> referenceQueue = new ReferenceQueue<Object>();   
  5. WeakReference<Object> weakReference = new WeakReference<Object>(referent, referenceQueue);   
  6.    
  7. assertFalse(weakReference.isEnqueued());   
  8. Reference<? extends Object> polled = referenceQueue.poll();   
  9. assertNull(polled);   
  10.    
  11. referent = null;   
  12. System.gc();   
  13.  
  14. assertTrue(weakReference.isEnqueued());   
  15. Reference<? extends Object> removed = referenceQueue.remove();   
  16. assertNotNull(removed);   
  17. }  
  18.  
  19.  @Test  
  20.  public void referenceQueue() throws InterruptedException {  
  21.   Object referent = new Object();    
  22.   ReferenceQueue<Object> referenceQueue = new ReferenceQueue<Object>();  
  23.   WeakReference<Object> weakReference = new WeakReference<Object>(referent, referenceQueue);  
  24.     
  25.   assertFalse(weakReference.isEnqueued());  
  26.   Reference<? extends Object> polled = referenceQueue.poll();  
  27.   assertNull(polled);  
  28.     
  29.   referent = null;  
  30.   System.gc();  
  31.  
  32.   assertTrue(weakReference.isEnqueued());  
  33.   Reference<? extends Object> removed = referenceQueue.remove();  
  34.   assertNotNull(removed);  
  35.  } 


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

【編輯推薦】

  1. 成為Java高手的重要過程
  2. Java GUI的發展和演化簡史
  3. Java正則表達式工具類實例
  4. 用Java壓縮文件解決沒有中文問題示例
  5. Java與C++語言在作用域上的差異淺析
責任編輯:彭凡 來源: javaeye
相關推薦

2017-11-15 19:30:08

Python內存泄露循環引用

2015-11-02 17:20:00

Java弱引用

2024-12-16 16:10:31

2021-01-21 14:06:57

云計算

2023-12-25 09:30:41

Java垃圾回收

2009-09-09 09:36:25

Linq對象引用

2009-04-10 09:43:00

Java輸出流異常

2013-08-19 17:14:04

.Net強引用弱引用

2013-07-31 09:03:45

2019-09-16 09:23:34

高并發編程CountDownLaCyclicBarri

2009-09-03 16:55:58

C#引用類型

2009-08-03 17:51:43

C#引用類型

2022-03-08 13:06:25

引用隊列jvm變量

2019-11-27 14:41:50

Java技術語言

2009-12-30 15:58:19

Silverlight

2014-03-12 10:19:54

iOS對象

2012-05-25 09:40:07

2009-08-19 16:39:44

C#值類型C#引用類型

2012-02-13 10:18:42

C++ 11

2015-05-14 15:38:40

javajava內存泄露
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲成人精品 | 成人精品一区二区三区中文字幕 | 国产精品99久久久久久大便 | 欧美一级二级三级 | 久久91精品国产 | 99re在线视频观看 | 精精国产xxxx视频在线播放7 | 理论片午午伦夜理片影院 | 国产亚洲www | 日韩成人在线观看 | av中文字幕在线 | 99精品国产在热久久 | 中文字幕在线观看精品 | 婷婷久久综合 | 日韩午夜场 | 欧美日韩成人在线 | 天天综合网永久 | 毛片黄| 日韩在线视频一区二区三区 | 天天曰天天干 | 超碰导航 | 亚洲精品在线视频 | 日韩毛片免费看 | 欧美一区在线视频 | 午夜一级黄色片 | 国产精品久久久久久久久久了 | 九九九久久国产免费 | 欧美精品一二区 | 污污免费网站 | 精品国产成人 | 国产视频二区 | 一区精品视频 | 成人免费视频在线观看 | 亚洲三区视频 | 久久免费福利 | av在线一区二区三区 | 欧美不卡一区二区三区 | 久久精品免费一区二区三 | 亚洲网站观看 | 99精品一区二区 | av国产精品 |