生活随笔
收集整理的這篇文章主要介紹了
                                
JVM之强引用、软引用、弱引用、虚引用
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.                        
 
                                
                            
                            
                            JVM之強引用、軟引用、弱引用、虛引用
 
 
整體架構強引用Reference軟引用SoftReference弱引用WeakReference軟引用和弱引用的適用場景WeakHashMap案例演示和解析ReferenceQueue引用隊列介紹虛引用PhantomReference 
 
1. 整體架構
 
 
 
 
2. 強引用Reference
 
 
 當內存不足,JVM開始垃圾回收,對于強引用的對象,就算是出現了00M也不會對該對象進行回收,死都不收。
  強引用是我們最常見的普通對象引用,只要還有強引用指向一個對象,就能表明對象還“活著”,垃圾收集器不會碰這種對象。在Java中最常見的就是強引用,把一個對象賦給一個引用變量,這個引用變量就是一個強引用。當一個對象被強引用變量引用時,它處于可達狀態,它是不可能被垃圾回收機制回收的,即使該對象以后永遠都不會被用到JVM也不會回收。因此強引用是造成Java內存泄漏的主要原因之一
  對于一個普通的對象,如果沒有其他的引用關系,只要超過了引用的作用域或者顯式地將相應(強)引用賦值為null,一般認為就是可以被垃圾收集的了〈當然具體回收時機還是要看垃圾收集策略)。
  圖解:
  
 
 
3. 軟引用SoftReference
 
 
 軟引用是一種相對強引用弱化了一些的引用,需要用java.lang.ref.SoftReference類來實現,可以讓對象豁免一些
  對于只有軟引用的對象來說,當系統內存充足時它不會被回收,當系統內存不足時它會被回收
  軟引用通常用在對內存敏感的程序中,比如高速緩存就有用到軟引用,內存夠用的時候就保留,不夠用就回收!
  示例:當內存充足時:
 
  示例:當內存不足時
 
  
 
4. 弱引用WeakReference
 
 
弱引用需要用Java.lang.ref.WeakReference類來實現,它比軟引用的生存期更短,對于只有弱引用的對象來說,只要垃圾回收機制一運行,不管JVM的內存空間是否是夠,都會回收該對象占用的內存。 
2.代碼示例:
 
public class WeakReferenceDemo {public static void main(String
[] args
) {Object o1 
= new Object();WeakReference
<Object> weakReference 
= new WeakReference<>(o1
);System
.out
.println(o1
);System
.out
.println(weakReference
.get());o1 
= null
;System
.gc();System
.out
.println("==============");System
.out
.println(o1
);System
.out
.println(weakReference
.get());}
}
 
執行結果
  
 
5. 軟引用和弱引用的適用場景
 
 
 假如有一個應用需要讀取大量的本地圖片:
 如果每次讀取圖片都從硬盤讀取則會嚴重影響性能,如果一次性全部加載到內存中又可能造成內存溢出。  此時使用軟引用可以解決這個問題。
 設計思路是:用一個HashMap來保存圖片的路徑和相應圖片對象關聯的軟引用之間的映射關系,在內存不足時,JVM會自動回收這些緩存圖片對象所占用的空間,從而有效地避免了00M的問題。  Map<String,SoftReference>imageCache=new HashMap<String,SoftReference>();
  
 
6. WeakHashMap案例演示和解析
 
 
 面試問上面的部分就很引出WeakHashMap,所以來說一說。
  概述:
 
 
 即當WeakHashMap的key為null,它也會被垃圾回收。
  代碼示例:
  
import java
.lang
.ref
.WeakReference
;
import java
.util
.HashMap
;
import java
.util
.WeakHashMap
;public class WeakReferenceDemo {public static void main(String
[] args
) {myHashMap();System
.out
.println("==========");myWeakHashMap();}private static void myWeakHashMap() {WeakHashMap
<Integer,String> map 
= new WeakHashMap<>();Integer key 
= new Integer(2);String value 
= "WeakHashMap";map
.put(key
,value
);System
.out
.println(map
);key 
= null
;System
.out
.println(map
);System
.gc();System
.out
.println(map
);}private static void myHashMap() {HashMap
<Integer,String> map 
= new HashMap<>();Integer key 
= new Integer(1);String value 
= "HashMap";map
.put(key
,value
);System
.out
.println(map
);key 
= null
;System
.out
.println(map
);System
.gc();System
.out
.println(map
);} 
執行結果:
  
 
7. ReferenceQueue引用隊列介紹
 
 
java提供了4種引用類型,在垃圾回收的時候,都有自己各自的特點。ReferenceQueue是用來配合引用工作的,沒有Referencequeue一樣可以運行創建引用的時候可以指定關聯的隊列,當GC釋放對象內存的時候,會將引用加入到引用隊列,如果程序發現某個虛引用已經被加入到引用隊列,那么就可以在所引用的對象的內存被回收之前采取必要的行動,這相當于一種通知機制。 
4.當關聯的引用隊列中有數據的時候,意味著引用指向的堆內存中的對象被回收。通過這種方式,JVM運行我們在對象被銷毀后,做一些我們自己想做的事情。
 
 
代碼測試: 
public class ReferenceQueueDemo {public static void main(String
[] args
) throws InterruptedException 
{Object o1 
= new Object();ReferenceQueue
<Object> referenceQueue 
= new ReferenceQueue();WeakReference
<Object> weakReference 
= new WeakReference<>(o1
,referenceQueue
);System
.out
.println(o1
);System
.out
.println(weakReference
.get());System
.out
.println(referenceQueue
.poll());System
.out
.println("=====================");o1 
= null
;System
.gc();Thread
.sleep(500);System
.out
.println(o1
);System
.out
.println(weakReference
.get());System
.out
.println(referenceQueue
.poll());}
} 
執行結果
  
 
8. 虛引用PhantomReference
 
 
 虛引用需要java.lang.ref.PhantomReference類來實現。
  顧名思義,就是形同虛設,與其他幾種引用都不同,虛引用并不會決定對象的生命周期。如果一個對象僅持有虛引用,那么它就和沒有任何引用一樣,在任何時候都可能被垃圾回收器回收,它不能單獨使用也不能通過它訪問
 對象,虛引用必須和引用隊列(ReferenceQueue)聯合使用。
  虛引用的主要作用是跟蹤對象被垃圾回收的狀態。僅僅是提供了一種確保對象被finalize以后,做某些事情的機制。PhantomReference的get方法總是返回null,因此無法訪問對應的引用對象。其意義在于說明一個對象己經進入俑finalization階段,可以被gc回收,用來實現比finalization機制更靈活的回收操作。
  換句話說,設置虛引用關聯的唯一目的,就是在這個對象被收集器回收的時候收到一個系統通知或者后續添加進一步的處理。Java技術允許使用finalize()方法在垃圾收集器將對象從內存中清除出去之前做必要的清理工作。
  代碼示例:
  
import java
.lang
.ref
.PhantomReference
;
import java
.lang
.ref
.ReferenceQueue
;public class PhantomReferenceDemo {public static void main(String
[] args
) throws InterruptedException 
{Object o1 
= new Object();ReferenceQueue
<Object> referenceQueue 
= new ReferenceQueue();PhantomReference
<Object> phantomReference 
= new PhantomReference<>(o1
,referenceQueue
);System
.out
.println(o1
);System
.out
.println(phantomReference
.get());System
.out
.println(referenceQueue
.poll());System
.out
.println("=====================");o1 
= null
;System
.gc();Thread
.sleep(500);System
.out
.println(o1
);System
.out
.println(phantomReference
.get());System
.out
.println(referenceQueue
.poll());}
} 
執行結果: 
                            總結
                            
                                以上是生活随笔為你收集整理的JVM之强引用、软引用、弱引用、虚引用的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                            
                                如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。