Java的四种引用:强应用,软引用,弱引用,虚引用
四种引用的不同之处仅在于垃圾回收时GC对他们的处理方式不同。在解说四种引用之前,我们先来看一下引用队列。
引用队列:当对象被gc回收之后,就会将该对象的引用加入引用队列。但是既然对象都已经被回收了,那为什么还要把该对象的引用保存起来呢?通常在对象被gc回收之后,都需要进行一些清理工作,比如如果你将对象的引用保存在WeakHashMap中,当对象被回收之后,就需要将引用从WeakHashMap中移除,防止map无休止的增长。
1、 强引用StrongReference
通常我们直接new出来的对象都是强引用的,例如StringBuffer buffer = new StringBuffer();我们知道在Jvm中对象都是通过引用来访问的,同一个对象可能有多个引用指向它。对于被强应用的对象,只要目前还有一个强应用指向它,那么该对象就无法被gc回收。
2、 软引用SoftReference
软引用是相对强应用来说相对较“软”的引用,只要内存足够,那么软引用指向的对象就不会被gc回收,但是如果内存不租了,就会被回收。
3、 弱引用WeakReference
弱引用是相对软应用更“弱”的引用,当gc在扫描jvm中的垃圾时,只要发现了某个对象是被软引用的,不管内存是否充足,该对象都会被回收。
WeakReferenceactivity = new WeakReference<>(widget);activity.get();复制代码
通过get()方法就可以获取到所引用的对象,但是因为弱引用的特性,我们经常会遇到activity.get()返回null的情况,所以
4、 虚引用PhantomReference
虚引用没有任何“引用”的意思,换句话说就是持有虚引用的对象不持有任何引用,它可能随时被gc回收。,就目前来看虚引用好像形同虚设,没有任何作用,但凡事存在均有理由,之所以设计虚引用是想通过它来跟踪gc回收对象的过程。虚引用与软引用、弱引用的不同之处就是它必须配合引用队列来使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。
ReferenceQueue queue = new ReferenceQueue ();PhantomReference pr = new PhantomReference (object, queue); 复制代码
总结
根据上面的分析描述可知:
- 从引用的强弱上依次为:强引用、软应用、弱引用、虚引用
- 软引用经常被用来设计高速cache
- 虚引用必须配合引用队列来使用