垃圾回收的原理是根據對象的可達性來決定是否回收該對象。對象可達或者說可得到的,是指對象可在應用中的某處找到,這意味着在棧中有一個引用指向此對象;也有多是一個引用指向的對象中包含一個引用指向此對象;也有可能中間有更多的鏈接。若是一個對象是可得到的,那麼垃圾回收器就不能釋放它,若是一個對象是不可得到的,釋放該對象就不會存在問題。java
若是想持有某個對象的引用,但願之後還能夠繼續訪問到該對象,可是也但願可以容許垃圾回收器釋放它,此時就應該想到Reference。這樣,你就能夠繼續使用該對象,並在內存耗盡前釋放該對象。緩存
以Reference對象做爲和普通引用之間的媒介。另外,必定不能有普通的引用指向那個對象,這樣才能達到上述目的。bash
SoftReference,WeakReference和PhantomReference由強到弱排列,強弱是指可得到性,更易失可得到性。其中SoftReference是用於實現內存敏感的高速緩存,在拋出OutOfMemoryError以前保證會調用垃圾回收器清理此類引用。WeakReference是爲實現規範映射而設計的,它不妨礙垃圾回收器回收映射的鍵或者值。規範映射的對象實例能夠在多處被同時使用,其中Thread中用以保存審計的類使用的WeakClassKey即是繼承自WeakReference。PhantomReference用以調度回收前的清理工做,比java終止機制更靈活。與soft和weak不一樣,phantomReferen的get方法老是返回null,而且,它不是由垃圾回收器自動清理,那麼這個類還能幹啥用呢,主要是作一些回收前的清理工做,相似finalize方法。ide
下面一段代碼:執行gc先後對比soft和weak,soft並無被回收,而weak被回收並被放入referencequeuethis
import java.lang.ref.*; import java.util.LinkedList; class VeryBig{ private static final int SIZE=10000; private long[] la = new long[SIZE]; private String ident; public VeryBig(String id){ this.ident = id; } @Override public String toString() { return this.ident; } protected void finalize(){ System.out.println("Finalizing " + ident); } } public class NesttyMain { private static ReferenceQueue<VeryBig> rq = new ReferenceQueue<VeryBig>(); public static void checkQueue(){ Reference<? extends VeryBig> inq = rq.poll(); if(inq!=null){ System.out.println("In queue: "+inq.get()); } } public static void main(String[] args){ int size=10; LinkedList<SoftReference<VeryBig>> sa = new LinkedList<SoftReference<VeryBig>>(); for (int i=0;i<size;i++){ sa.add(new SoftReference<VeryBig>(new VeryBig("Soft"+i),rq)); System.out.println("Just created: "+sa.getLast()); checkQueue(); } LinkedList<WeakReference<VeryBig>> wa = new LinkedList<WeakReference<VeryBig>>(); for (int i=0;i<size;i++){ wa.add(new WeakReference<VeryBig>(new VeryBig("Weak"+i),rq)); System.out.println("Just created: "+wa.getLast()); checkQueue(); } SoftReference<VeryBig> s = new SoftReference<VeryBig>(new VeryBig("Soft")); WeakReference<VeryBig> a = new WeakReference<VeryBig>(new VeryBig("Weak")); //此處執行gc後weakreference的linkedlist被回收,回收對象被存放到rq中,在下面執行phantom的checkqueue打印的就是weakreference //執行get返回的是null System.gc(); LinkedList<PhantomReference<VeryBig>> pa = new LinkedList<PhantomReference<VeryBig>>(); for (int i=0;i<size;i++){ pa.add(new PhantomReference<VeryBig>(new VeryBig("Phantom"+i),rq)); System.out.println("Just created: "+pa.getLast()); checkQueue(); } } }
輸出:設計
Just created: java.lang.ref.SoftReference@61bbe9ba Just created: java.lang.ref.SoftReference@610455d6 Just created: java.lang.ref.SoftReference@511d50c0 Just created: java.lang.ref.SoftReference@60e53b93 Just created: java.lang.ref.SoftReference@5e2de80c Just created: java.lang.ref.SoftReference@1d44bcfa Just created: java.lang.ref.SoftReference@266474c2 Just created: java.lang.ref.SoftReference@6f94fa3e Just created: java.lang.ref.SoftReference@5e481248 Just created: java.lang.ref.SoftReference@66d3c617 Just created: java.lang.ref.WeakReference@63947c6b Just created: java.lang.ref.WeakReference@2b193f2d Just created: java.lang.ref.WeakReference@355da254 Just created: java.lang.ref.WeakReference@4dc63996 Just created: java.lang.ref.WeakReference@d716361 Just created: java.lang.ref.WeakReference@6ff3c5b5 Just created: java.lang.ref.WeakReference@3764951d Just created: java.lang.ref.WeakReference@4b1210ee Just created: java.lang.ref.WeakReference@4d7e1886 Just created: java.lang.ref.WeakReference@3cd1a2f1 Just created: java.lang.ref.PhantomReference@2f0e140b Just created: java.lang.ref.PhantomReference@7440e464 Just created: java.lang.ref.PhantomReference@49476842 In queue: null Just created: java.lang.ref.PhantomReference@78308db1 In queue: null Just created: java.lang.ref.PhantomReference@27c170f0 In queue: null Just created: java.lang.ref.PhantomReference@5451c3a8 In queue: null Just created: java.lang.ref.PhantomReference@2626b418 In queue: null Just created: java.lang.ref.PhantomReference@5a07e868 In queue: null Just created: java.lang.ref.PhantomReference@76ed5528 In queue: null Just created: java.lang.ref.PhantomReference@2c7b84de In queue: null Finalizing Weak Finalizing Weak9 Finalizing Weak8 Finalizing Weak7 Finalizing Weak6 Finalizing Weak5 Finalizing Weak4 Finalizing Weak3 Finalizing Weak2 Finalizing Weak1 Finalizing Weak0 Process finished with exit code 0