一、强引用
通过new出来的对象就是强引用,比如Object obj = new Object,强引用不会被垃圾回收器回收,当内存空间不足时,Java虚拟机会抛出OutOfMemoryError异常使程序终止。来看一个例子;
声明一个类,使其占大概1Gb的空间,假设我们内存只有2G
public class Obj {
byte[] objs = new byte[1024*1024*1024];
}
Main方法中创建一个Obj对象:
Obj obj = new Obj();
此时没有任何异常,那么我们来new两个Obj
Obj obj = new Obj();
Obj obj = new Obj();
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
可以看到,当我们new两个Obj时,直接抛出了异常,可见强引用类型不会被垃圾回收器回收。
二、软引用
如果一个对象是软引用,且内存空间足够时,垃圾回收器就不会回收它,如果内存空间不足时,就会回收这些对象的内存。
//软引用
SoftReference<Obj> obj = new SoftReference<Obj>(new Obj());
//强引用
Obj obj2 = new Obj();
如上代码创建了一个软引用和一个强引用,当创建强引用时,内存空间肯定已经不够了,所以上面的弱引用会被回收,我们打印一下看看:
System.out.println(obj.get());
System.out.println(obj2);
输出:
null
.Obj@15db9742
可以看到这个时候弱引用的obj为null,说明他已经被垃圾回收器回收掉了,所以当内存空间不足时,弱引用会被回收。
接下来看一下内存空间足够的情况;
SoftReference<Obj> obj = new SoftReference<Obj>(new Obj());
System.out.println(obj.get());
System.gc();
Thread.sleep(2000);
System.out.println(obj.get());
上面我们只创建了一个弱引用,然后手动调用gc回收,休眠2s保证gc执行完成,这时再打印obj:
.Obj@15db9742
.Obj@15db9742
可以看到手动调用gc回收后,弱引用obj依旧存在,说明当内存空间足够时,弱引用不会被回收。
三、弱引用
弱引用一旦手动调用gc,或者垃圾回收器发现了弱引用对象,无论内存空间是否足够,弱引用都会被回收。
WeakReference<Obj> obj = new WeakReference<Obj>(new Obj());
System.out.println(obj.get());
System.gc();
Thread.sleep(2000);
System.out.println(obj.get());
上面代码创建了一个弱引用,并打印,随后手动调用了gc,再次打印,我们看下结果
.Obj@15db9742
null
可以看到,一旦我们调用gc之后,弱引用就被回收了。
四、虚引用
故名思意:虚,如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收。看下面一段代码;
ReferenceQueue referenceQueue = new ReferenceQueue();
PhantomReference<Obj> obj = new PhantomReference<>(new Obj(),referenceQueue);
System.out.println(obj.get());
输出:null
为什么只创建了一个虚引用,却拿不到它呢?因为在虚引用中,无法拿到虚引用的对象。
那么上面的referenceQueue是什么呢?
虚引用创建时,必须指定一个ReferenceQueue对象,可以理解为引用队列,当虚引用被回收时,该对象就会被垃圾回收器放到这个队列中。
ReferenceQueue referenceQueue = new ReferenceQueue();
PhantomReference<Obj> obj = new PhantomReference<>(new Obj(),referenceQueue);
System.gc();
Thread.sleep(2000);
System.out.println(referenceQueue.poll()); 输出:java.lang.ref.PhantomReference@15db9742
所以我们可以通过referenceQueue来判断虚引用对象是否已经被回收。
五、总结
强引用:不会被回收。
软引用:内存不足时会被回收。
弱引用:垃圾回收时会被回收。
虚引用:垃圾回收时会被回收。
网友评论