Java的引用
Object obj = new Object();
这时创建的Object对象就存在一个引用,这个引用是最普通也最常用的引用,为了与软引用区分,我们将之称为强引用。当一个对象存在强引用时,GC(Java垃圾回收机)运行时,无论如何都不会将这个对象回收
Java的软引用
当一个对象之存在软引用时,GC在运行时,如果发现内存不足,就会优先回收掉这个对象,而不是抛出OutOfMemory错误。创建一个弱引用的方法就是使用SoftReference对象
public void softTest(){
Image img = Toolkit.getDefaultToolkit().getImage("hello.png");
this.softRef = new SoftReference<Image>(img);
}
这样就创建了当softTest这个函数执行完后,由于变量img结束生命周期,hello.png图像没有被任何变量强引用,只被softRef对象软引用。要使用这个图片对象,可以调用get()方法返回图片对象的强引用。如果软引用对象被GC回收,该方法返回的就是null
Image img = softRef.get();
通常软引用对象和ReferenceQueue对象联合使用,这是因为当一个软引用对象被回收时,会使SoftReference这个对象本身无用。如果大量的SoftReference没有被回收掉,势必造成很大的内存浪费,因此我们要避免对SoftReference对象使用强引用,而是将其加入到一个List中
private ReferenceQueue<Image> rQueue = new ReferenceQueue<Image>();
private List<SoftReference<Image> > softRefList = new LinkedList<SoftReference<Image> >();
public void softTest(){
Image img = Toolkit.getDefaultToolkit().getImage("hello.png");
SoftReference<Image> softRef = new SoftReference<Image>(img, rQueue);
softRefList.add(softRef);
}
当一个软引用对象被GC回收时,SoftReference对象就会将自己加入到ReferenceQueue队列中,所以我们只要隔一段时间检查队列,就可以知道软引用对象是否被GC回收。如果软引用对象被回收,则从List中移除这个SoftReference这个对象本身
while(true){
Object softRef = rQueue.poll();
if(softRef == null){
break;
}
softRefList.remove(softRef);
}
Java的弱引用
Java的弱引用与Java的软引用用法类似,弱引用使用的引用对象是WeakReference,一般与ReferenceQueue对象联合使用。弱引用与软引用的区别是:当GC运行时,如果发现一个对象只存在弱引用,就会立即回收它。但GC一般运行在低优先级线程上,不一定能够即使发现弱引用对象,所以弱对象可以在内存中存在一定的时间。
其实Java中还存在一种虚引用。虚引用使用的对象是PhantomReference,PhantomReference的get()方法返回值总是null。虚引用比弱引用的生命周期更短,这种引用形同虚设,无法通过get()方法返回虚引用对象的强引用,虚引用只有在跟踪一个对象被GC回收时使用到。虚引用与ReferenceQueue联合使用,当一个对象被GC回收,可以明白的知道这个对象被回收掉了。