Java 对象的引用划分为4种,它们由强到弱依次是强引用、软引用、弱引用、虚引用。这样划分的作用是可以更好的控制对象的声明周期,有利于JVM 进行垃圾回收。
强引用(StrongReference)
强引用就是我们最常见的普通对象引用,通常我们通过new
来创建的对象所产生的引用就是强引用,强引用的对象不可被JVM垃圾收集器回收。
比如下面这段代码,obj
和str
都是强引用。
1 | Object obj = new Object(); |
只要某个对象有强引用与之关联,JVM必定不会回收这个对象,即使在内存不足的情况下,JVM宁愿抛出OOM的错误也不会回收这种对象。比如下面的代码中
1 | public class Main { |
当运行至Object[] objArr = new Object[1000];
时,即使内存不足抛出OOM错误,也不会回收object
所引用的对象。不过要注意的是当fun1()
方法执行完毕后,object
、objArr
都已经不存在,所以他们指向的对象会被JVM回收。
如果想中队强引用和某个对象之间的关联,可以显示的将引用赋值为null(如object = null),这样JVM就会在合适的时机回收原object
所指向的对象。
软引用(SoftReference)
软引用是一种相对强引用弱化一些的引用,可以让对象豁免一些垃圾收集,只有当 JVM 认为内存不足时,才会去试图回收软引用指向的对象。JVM 会确保在抛出 OutOfMemoryError 之前,清理软引用指向的对象。软引用通常用来实现内存敏感的缓存,如果还有空闲内存,就可以暂时保留缓存,当内存不足时清理掉,这样就保证了使用缓存的同时,不会耗尽内存。
1 | SoftReference<String> sr = new SoftReference<String>(new String("hello")); |
软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被回收,则这个软引用进入到与之关联的引用队列中。
弱引用(WeakReference)
弱引用并不能使对象豁免垃圾收集,仅仅是提供一种访问在弱引用状态下对象的途径。这就可以用来构建一种没有特定约束的关系,比如,维护一种非强制性的映射关系,如果试图获取时对象还在,就使用它,否则重现实例化。它同样是很多缓存实现的选择。
1 | public class Main { |
同样弱引用也可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被回收,则将这个若引用进入到与之关联的引用队列中。
虚引用(PhantomReference)
虚引用也被翻译为幻象引用,你不能通过它访问对象。幻象引用仅仅是提供了一种确保对象被 finalize 以后,做某些事情的机制。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。
虚引用必须和引用队列联合使用。
1 | public class Main { |