[关闭]
@c102zkl 2018-08-03T07:18:22.000000Z 字数 2298 阅读 550

Java四引用——强、软、弱、虚

Java小知识


作用及概念

Java从JDK1.2版本开始,把对象的引用分为四种级别:强引用、软引用、弱引用 、虚引用

强引用使用最普遍的引用,垃圾回收器绝不会回收它。当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,也不会回收强引用对象。

软引用:如果一个对象只具有软引用,内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存。软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收器回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。

弱引用发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被垃圾回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中。

虚引用不会决定对象的生命周期。如果一个对象仅持有虚引用,在任何时候都可能被垃圾回收器回收。虚引用主要用来跟踪对象被垃圾回收器回收的活动。虚引用必须和引用队列(ReferenceQueue)联合使用。程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。如果程序发现某个虚引用已经被加入到引用队列,那么就可以内存被回收之前采取必要的行动。

Java中提供这四种引用类型主要有两个目的:


使用方法

在java.lang.ref包中提供了三个类:SoftReference类、WeakReference类和PhantomReference类,他们分别对应软引用、弱引用和虚引用。这是三个类的父类都是Reference类,他们的方法基本上都一样,我们以SoftReference为例:

  1. public class SoftReference<T> extends Reference<T> {
  2. private T referent; /* Treated specially by GC */
  3. // 构造方法1,生成指向referent对象的软引用
  4. public SoftReference(T referent)
  5. // 构造方法2,生成指向referent对象的软引用,并将这个软引用和引用队列q绑定在一起
  6. public SoftReference(T referent, ReferenceQueue<? super T> q)
  7. // 通过get方法得到,软引用所指向的对象
  8. public T get()
  9. }

SoftReference类从父类Reference中继承了一个referent变量,这个变量就是专门用来存储软引用所指向对象的,下面的例子中会讲到

如果这个引用指向的对象已经被回收,那么get( )将返回null

ReferenceQueue 引用队列

还有一个ReferenceQueue类这就是上面提到的引用队列,:它可以和上面三个类联合使用,以便跟踪JVM中所回收的对象的活动。

  1. public class ReferenceQueue<T> {
  2. public Reference<? extends T> poll() //将队列顶端的元素抛出
  3. public Reference<? extends T> remove() // 将队列元素删除
  4. }

demo 例子

软引用(softReference)用来描述一些还有用但是并非必须的对象,在Java中用java.lang.ref.SoftReference类来表示。对于软引用关联着的对象,只有在内存不足的时候JVM才会回收该对象。因此,这一点可以很好地用来解决OOM的问题,并且这个特性很适合用来实现缓存:比如网页缓存、图片缓存等。

  1. SoftReference<T> sr = new SoftReference<T>(new Object());

软引用使用例子传送门:https://www.cnblogs.com/mjorcen/p/3968018.html

弱引用(WeakReference),一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。Java源码中的java.util.WeakHashMap中的key就是使用弱引用,我的理解就是,一旦我不需要某个引用,JVM会自动帮我处理它,这样我就不需要做其它操作。

  1. WeakReference<T> wrf = new WeakReference<T>(new Object());

弱引用使用例子传送门:http://www.importnew.com/21206.html

虚引用(PhantomReference),虚引用的回收机制跟弱引用差不多,但是它被回收之前,会被放入ReferenceQueue中。注意,其它引用是被JVM回收后才被传入ReferenceQueue中的。由于这个机制,所以虚引用大多被用于引用销毁前的处理工作。还有就是,虚引用创建的时候,必须带有ReferenceQueue,使用例子:

  1. PhantomReference<T> prf = new PhantomReference<T>(new Object(), new ReferenceQueue<>());

对象销毁前的一些操作,比如说资源释放等。Object.finalize()虽然也可以做这类动作,但是这个方式即不安全又低效(传送门:http://blog.csdn.net/aitangyong/article/details/39450341),so。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注