1 代码实现
package pkgOne;
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.util.WeakHashMap;
public class LearnReference {
public static void main(String[] args) {
/**
* 强引用
* 不会被gc回收,并且在java.lang.ref里也没有实际的对应类型
* 比如下面的stus
*/
Stus stus=new Stus(18, "lili");
ReferenceQueue<Stus> queue=new ReferenceQueue<Stus>();
//
/**
* 软引用
* 在JVM报告内存不足的时候才会被GC回收,否则不会回收,
* 正是由于这种特性软引用在caching和pooling中用处广泛
* 可以发现下面gc前后,软引用都没有被回收,因为没有内存不足
*/
SoftReference<Stus> soft=new SoftReference<Stus>(stus, queue);
stus=null;
System.out.println("gc前,软引用:"+soft.get());
System.gc();
System.out.println("gc后,软引用:"+soft.get());
System.out.println("队列:"+queue.poll());
System.out.println("------------------------------");
/**
* 弱引用
* 当GC一但发现了弱引用对象(所指向的对象被置为null),
* 将会释放WeakReference所引用的对象
* 应用,比如WeakHashmap
*/
stus=new Stus(22, "pp");
WeakReference<Stus> weak=new WeakReference<Stus>(stus,queue);
stus=null;
System.out.println("gc前,弱引用:"+weak.get());
System.gc();
System.out.println("gc后,弱引用:"+weak.get());
System.out.println("队列:"+queue.poll());
System.out.println("队列:"+queue.poll());
System.out.println("------------------------------");
//虚引用
/**
* 虚引用
* 调用phanRef.get()不管在什么情况下会一直返回null
* 在对象被JVM决定需要GC后, 将自己enqueue到RQ中.
* 他通常用来在一个对象被GC前作为一个GC的标志
* 虚引用可以用来做对象被回收之前的清理工作。有时候,他们比finalize()方法更灵活
*/
stus=new Stus(24, "xx");
PhantomReference<Stus> phantom=new PhantomReference<Stus>(stus, queue);
System.out.println("stus置为null前,phantom引用:"+phantom.get());
System.gc();//stus没有被置为null,gc不起作用
System.out.println("stus置为null前的队列:"+queue.poll());
stus=null;
System.out.println("gc前,phantom引用:"+phantom.get());
System.gc();
System.out.println("gc后,phantom引用:"+phantom.get());
System.out.println("gc后的队列:"+queue.poll());
System.out.println("------------------------------");
/**
* WeakHashMap
* 是HashMap的WeakReference实现, 他使用WeakReference封装了Entry的Key
*
*/
/**
* 如果这个WeakHashMap的key仅有这个Map持有弱引用,
* 则当JVM GC执行时,它的key和value会被GC.
*/
WeakHashMap<Stus, Integer> map=new WeakHashMap<Stus,Integer>();
map.put(new Stus(0, "asd"), 2);
System.out.println("gc前,map:"+map);
System.gc();
System.out.println("gc后,map:"+map);
/**
* 如果这个key还有别的引用则不会被GC.
*/
stus=new Stus(100, "llq");
map.put(stus, 3);
System.out.println("gc前,map:"+map);
System.gc();
System.out.println("gc后,map:"+map);
/**
* 将“别的引用置为空”,则会被gc
*/
stus=null;
System.gc();
System.out.println("stus置为null,gc后,map:"+map);
}
}
class Stus{
private int age;
private String name;
public Stus(int age,String name) {
// TODO Auto-generated constructor stub
this.age=age;
this.name=name;
}
public String getInfo() {
return "name:"+name+" , "+"age:"+age;
}
}
2 参考文章
前两篇文章非常不错