描述
首先什么是引用?什么是对象?这是一个基础的问题。我们看看一些简单的代码。1
2Object a;
a = new Object();
这里的a是一个引用,Object a只是声明了一个Object的引用,在第二行执行前,a是一个没有指向的引用。第二行中的new Object()建立了对象存到了堆中,由a = new Object()赋给了a这个引用。1
2
3
4Object a;
Object b;
a = new Object();
b=a;
同一个对象可以有多个引用。1
2
3
4Object a;
a = new Object();
a = new Object();
a = new Object();
一个引用可以指向多个对象。
引用分类
强引用
我们平时使用的最简单的就是强引用,比如1
String s= "a";
强引用在java的垃圾回收机制中不会被回收,即使内存不够也不会回收,只会抛出OutOfMemoryError异常并终止程序。
软引用
软引用通过SoftReference类实现。1
2Object a = new Object();
SoftReference sa = new SoftReference(a);
这里的Object有两个引用,一个是a,是对其对象的强引用,一个是sa是对其的软引用,也可以这样单独建立一个软引用。1
SoftReference<Object> sa = new SoftReference(new Object());
不同于强引用,在java的垃圾回收机制中如果出现内存不足的情况,这些软引用的对象会直接被回收。正因为这一特点,往往可以用来实现缓存。
弱引用
软引用通过WeakReference类实现。1
2Object a = new Object();
WeakReferencesa = new WeakReference(a);
同样这里的Object有两个引用,一个是a,是对其对象的强引用,一个是sa是对其的弱引用,也可以这样单独建立一个弱引用。1
WeakReferencesa<Object> sa = new WeakReferencesa(new Object());
对于弱引用在垃圾回收机制中是这样运作的,如果没有其他的强引用或是软引用而只是一个弱引用的话,那么会直接被回收。但是我们不确定回收机制运行的具体时间,所以我们无法确定具体的回收时间。
虚引用
虚引用与其他三种都不同,它可以说是没有引用,使用与不使用并不会改变相关对象的生命周期。1
2ReferenceQueue<Object> queue = new ReferenceQueue<Object>();
PhantomReference<Object> sa = new PhantomReference(new Object(),queue);
使用虚引用必须要和ReferenceQueue一起使用,当回收机制在回收时发现相关的对象还保留有虚引用时,会将其加入与之关联的ReferenceQueue中,我们可以通过对ReferenceQueue的操作来查看其是否被回收,所以一般使用虚引用来追踪回收过程。
小结
根据不同的需求,我们可以设置不同的引用类型进行内存管理,优化我们的程序,源码分析详见Java源码阅读——Reference。