Java引用类型

Java中,引用分为强引用,弱引用,虚引用,软引用。我们大多数情况下使用的都是强引用,比如Cat c = new Cat(),,c就是一个指向Cat实例的强引用,但是某些情况下,需要使用其他的引用类型。

弱引用

弱引用和强引用一样,指向一个对象实例,其区别在于GC。对于强引用,只要有强引用存在,其指向的对象就一定不会GC,对于弱引用,当一个对象实例只有弱引用,没有强引用时,GC一旦运行,该对象就会被回收。而GC运行的时机是不确定的,因此弱引用指向的对象被回收的时机也是不确定的。

使用场景

考虑这样的使用场景:在查询数据访问层接口时,有时可能需要查询刚刚查过的信息。如果我们读完信息就将对象销毁,那么每次查询都要重新构建对象,如果我们将每次查询完的结果保存在内存中,这显然造成了内存的浪费。

一种复杂的解决方案是使用缓存算法,更为简单的方法是使用弱引用。

例子

import java.lang.ref.WeakReference;

public class Main
{
    public static void main(String[] args) throws InterruptedException
    {
        Cat c = new Cat("Tom");
        WeakReference<Cat> ref = new WeakReference<Cat>(c);
        c = null;
        while(true)
        {
            new Object();
            System.out.println(ref.get() == null ? "null" : ref.get().getName());
        }
    }
}

上述代码中创建了Cat实例的弱引用。然后在死循环中,为了触发GC,不断创建Object。运行后,可以观察到,一段时间之后,输出从Tom变为了null。

ReferenceQueue

构造弱引用WeakReference时,我们可以传入一个ReferenceQueue,即引用队列。当弱引用指向的实例被GC后,其WeakReference指向null,也就是说,这个弱引用对象本身也没用了,这时弱引用对象就会被存入引用队列。

利用这个队列,我们能够实现检查哪些对象被垃圾回收了。

软引用和虚引用

这里我们直接对比一下Java的四种引用类型。

  • 强引用:只要引用存在,对象就不会被GC。
  • 软引用:当JVM内存不足时,对象会被GC,引用可被存入引用队列。
  • 弱引用:当GC线程触发时对象会被GC,引用可被存入引用队列。
  • 虚引用:虚引用持有的对象和不存在一样,任何时候都会被GC。虚引用必须配合引用队列。
作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。