一、强、软、弱、虚引用
1.强引用
Object obj = new Object()
,这种通过关键字new
创建的对象所关联的引用,就是强引用。- 当JVM内存不足时,JVM会抛出
OutOfMemoryError(OOM)
,使程序异常终止,也不会回收具有强引用的对象来解决内存不足的问题。- 对于一个普通的对象,如果没有其他的引用关系,只要超过了引用的作用域或者显式的将相应强引用赋值为null,就是可以被垃圾回收器回收的了,具体回收时机取决于垃圾回收策略。
2.软引用
- 软引用通过
SoftReference
类实现;软引用的生命周期比强引用短一些。- 只有当JVM认为内存不足时,才试图回收软引用指向的对象:即JVM会确保在抛出
OutOfMemoryError
之前,清理软引用指向的对象。- 软引用可以和一个引用队列(
ReferenceQueue
)联合使用,如果软引用所引用的对象被垃圾回收期回收,java虚拟机就会把这个软引用加入到与之关联的引用队列中;之后可以调用ReferenceQueue.poll()
方法检查是否有所关心的对象被回收;如果队列为null,将返回null,否则返回队列中前面的一个Reference对象。
- 引用场景:软引用通常用来实现内存敏感的缓存。如果还有空闲内存,就可以暂时保留缓存,当内存不足时清理,这样保证了使用缓存的同时,不会耗尽内存。
3.弱引用
- 弱引用通过
WeakReference
类实现;弱引用的生命周期比软引用短。- 垃圾回收器线程一旦发现具有弱引用的对象,不管当前内存空间是否足够,都会回收它的内存;由于垃圾回收器是一个优先级很低的线程,因此不一定会很快的回收弱引用的对象。
- 弱引用可以和一个引用队列(
ReferenceQueue
)联合使用,如果引用所引用的对象被回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中。
- 应用场景:弱引用同样可用于内存敏感的缓存。
4.虚引用
- 虚引用也叫幻象引用,通过
PhantomReference
类实现无法通过虚引用访问对象的任何属性或函数。- 虚引用仅仅是提供一种确保对象被finalize之后,做某些事情的机制。
- 如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何使用都可能被垃圾回收器回收。
- 虚引用必须和引用队列(
ReferenceQueue
)联合使用;当垃圾回收器准备回收一个对象时,如果发现持有虚引用,则会在回收对象之前,把这个虚引用加入到与之关联的引用队列中。- code:
ReferenceQueue queue = new ReferenceQueue ();
PhantomReference pr = new PhantomReference (object, queue);
程序可以通过判断引用队列是否已经加入了虚引用,来了解被引用的对象是否需要被垃圾回收。如果程序发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取一些程序行动。
- 应用场景:可以来跟踪对象被垃圾回收器回收的活动,当一个虚引用关联的对象被垃圾收集器回收之前会收到一条系统通知。