美文网首页
Java中的四种引用 - 强软弱虚

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

作者: silence_J | 来源:发表于2020-08-10 20:30 被阅读0次

    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中的四种引用 - 强软弱虚

          本文链接:https://www.haomeiwen.com/subject/pcqhohtx.html