Java中的四种引用 - 强软弱虚

Java中有四种引用,分别是:强引用、软引用、弱引用、虚引用。

什么是引用?
比如Object o = new Object(),声明了一个变量o,它指向new出来的Object对象,这就是一个引用。在Java的四种引用中,最常用的形式,如Object o = new Object(),就是强引用。

强引用

普通的引用NormalReference,是默认的引用,也就是强引用。只
要有一个引用指向这个对象,那么这个对象就不是垃圾,一定不会被垃圾回收器回收,只有没有引用指向它时才会被回收。

通过一个小程序理解强引用。

Java进行垃圾回收时会调用finalize方法,下面程序中重写了这个方法,方便观察什么时候进行了垃圾回收。

public class T01_NormalReference {
     

    public static void main(String[] args) {
     

        OverridFinalize instance = new OverridFinalize();
        
        // 注掉这句代码时,上面new的对象不会被回收
        instance = null;

        // 手动触发gc
        System.gc();

        // 不让main线程停止
        while (true) {
     }
    }

}

// 实际开发中不会重写finalize方法,这里是为了方便观察
class OverridFinalize {
     
    @Override
    protected void finalize() throws Throwable {
     
        System.out.println("自动垃圾回收,finalize被调用");
    }
}

让instance = null后没有引用指向对象了,会被垃圾回收器回收。

软引用

SoftReference叫软引用,当有一个对象被一个软引用所指向的时候,只有系统内存不够用的时候,触发gc才会回收它。

使用方法是new一个SoftReference的时候传入一个要指向的对象。

// 注意:softReference这个引用也是强引用,它指向SoftReference这个对象
// 这里的软引用指的是指向new Object()的引用,也就是SoftReference类中的T
SoftReference<Object> softReference = new SoftReference<>(new Object());

软引用的使用场景:适合做缓存用。比如从数据库查出一堆数据,缓存到内存里能方便再次查询,再次查只要到内存中取就行,不用再查数据库。但是heap装不下新的数据时会进行垃圾回收,软引用对象会被回收掉。

弱引用

弱引用WeakReference,只要遭遇到gc就会回收。与软引用的区别是,垃圾回收不一定回收软引用对象,只有空间不够了才会回收它,所以软引用的生存周期还是比较长的;弱引用是,只要垃圾回收看到这个弱引用对象,就直接回收。只要gc就回收。

WeakReference weakReference = new WeakReference<>(new Object())

如果有另外一个强引用指向了这个弱引用之后,只要强引用消失,这个弱引用就也一定是被回收了,一般用在容器里。

Java源码中的 java.util.WeakHashMap 中的 key 也是使用弱引用,可以理解为, 一旦不需要某个引用,JVM会自动帮我处理它,这样我就不需要做其它操作。

ThreadLocal源码中就使用了弱引用。

虚引用

虚引用就干一件事,就是管理堆外内存的。虚引用的构造方法至少都是两个参数的,第二个参数必须是一个队列ReferenceQueue 。也就是,虚引用创建的时候,必须带有 ReferenceQueue 。虚引用在常见开发工作中基本没用,是写JVM(虚拟机)的人用的。

虚引用的回收机制跟弱引用差不多,但是它被回收之前,会被放入 ReferenceQueue 中。注意 ,其它引用是被JVM回收后才被传入 ReferenceQueue 中的。由于这个机制,所以虚引用大多被 用于引用销毁前的处理工作。

可用场景: 对象销毁前的一些操作,比如说资源释放等。** Object.finalize() 虽然也可以做 这类动作,但是这个方式即不安全又低效

PhantomReference<String> prf = new PhantomReference<String>(new String("str"), new ReferenceQueue<>()); 

上诉所说的几类引用,都是指对象本身的引用,而不是指 Reference 的四个子类的引用 ( SoftReference 等)。

你可能感兴趣的:(Java笔记)