1. 程式人生 > >java 強弱軟虛 四種引用,以及用到的場景

java 強弱軟虛 四種引用,以及用到的場景

優先 時間 重新 通過 如果 sof queue hashcode 等待

1、利用軟引用和弱引用解決OOM問題:用一個HashMap來保存圖片的路徑和相應圖片對象關聯的軟引用之間的映射關系,在內存不足時,JVM會自動回收這些緩存圖片對象所占用的空間,從而有效地避免了OOM的問題;

2、通過軟引用對象重獲方法實現java對象的高速緩存:比如我們創建了一個Employee類,如果每次需要查詢一個雇員的信息。哪怕是幾秒鐘之前剛剛查詢過的,都要重新構建一個實例,這是需要消耗很多時間的。我們可以通過軟引用和HashMap的結合,先是保存引用方面:以軟引用的方式對一個Employee對象的實例進行引用並保存該引用到HashMap上,key為此雇員的id,value為這個對象的軟引用,另一方面是取出引用,緩存中是否有該Employee實例的軟引用,如果有,從軟引用中取得 。如果沒有軟引用,或者從軟引用中得到的實例是null,重新構建一個實例,並保存對這個新建實例的軟引用;

3、強引用:如果一個對象具有強引用,它就不會被垃圾回收器回收。即使當前內存空間不足,JVM也不會回收它,而是拋出OutOfMemoryError錯誤,使程序異常終止。如果想中斷強引用和某個對象之間的關聯,可以顯示的將引用賦值為null,這樣一來的話,JVM在合適的時間就會回收對象;

4、弱引用:具有弱引用的對象擁有的生命周期更短暫。因為當JVM進行垃圾回收,一旦發現弱引用對象,無論當前內存空間是否充足,都會將弱引用回收。不過由於垃圾回收器是一個優先級較低的線程,所以並不一定能迅速發現弱引用對象;

5、虛引用:顧名思義,就是形同虛設,如果一個對象僅持有虛引用,那麽它相當於沒有引用,在任何時候都有可能被垃圾回收器回收。

public static void soft() throws Exception{
Object obj = new Object();
ReferenceQueue rq = new ReferenceQueue<>();
SoftReference sr = new SoftReference(obj, rq); //創建關於obj的軟引用,使用引用隊列
System.out.println(sr.get()); //get方法會輸出這個obj對象的hashcode
System.out.println(rq.poll()); //輸出為null
obj = null;
System.gc();
Thread.sleep(200); //因為finalizer線程優先級很低,所以讓線程等待200ms
System.out.println(sr.get()); //因為堆空間沒滿,可有可無的特性,所以還是會輸出這個obj對象的hashcode

System.out.println(rq.poll()); //自然隊列為null
}

public static void weak() throws Exception{
Object obj = new Object();
ReferenceQueue rq = new ReferenceQueue<>();
WeakReference wr = new WeakReference(obj,rq);
System.out.println(wr.get());
System.out.println(rq.poll());
obj = null;
System.gc();
Thread.sleep(200);
System.out.println(wr.get()); //這時候會輸出null
System.out.println(rq.poll()); //rq隊列裏也會存放這個弱引用,輸出它的hashcode
}

java 強弱軟虛 四種引用,以及用到的場景