垃圾回收的原理是根据对象的可达性来决定是否回收该对象。对象可达或者说可得到的,是指对象可在应用中的某处找到,这意味着在栈中有一个引用指向此对象;也有多是一个引用指向的对象中包含一个引用指向此对象;也有可能中间有更多的链接。若是一个对象是可得到的,那么垃圾回收器就不能释放它,若是一个对象是不可得到的,释放该对象就不会存在问题。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