美文网首页
Java中的四种引用

Java中的四种引用

作者: 钢牙仔 | 来源:发表于2020-11-23 22:24 被阅读0次
    static class Person {
        String mName;
        public Person(String name) {
            mName = name;
        }
        @Override
        public String toString() {
            return "person[" + mName + "]";
        }
    }

1.强软弱虚四种引用

1.1 强引用

    public static void strongRef() {
        try {
            Person person = new Person("张三");
            Person strong = person;
            person = null;
            System.gc();
            Thread.sleep(1000);
            System.out.println(strong);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

执行结果:

person[张三]

解释:
强引用是JVM的默认实现,即使内存不足会导致OOM(OutOfMemory)时,强引用关联的对象也不会被回收。

1.2 软引用

       public static void softRef() {
            try {
                Person person = new Person("李四");
                ReferenceQueue<Person> rq = new ReferenceQueue<Person>();
                SoftReference<Person> sr = new SoftReference<Person>(person, rq);
                person = null;
                System.gc();
                Thread.sleep(1000);
                System.out.println("sr.get():" + sr.get());
                System.out.println("rq.poll():" + rq.poll());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

内存足够的情况下的执行结果:

sr.get():person[李四]
rq.poll():null

内存不足的情况下的执行结果:

sr.get():null
rq.poll():java.lang.ref.SoftReference@15db9742

解释:

  1. 某个对象只被软引用关联,当JVM内存不足时,该对象会被回收。也就是说在JVM抛出OutOfMemoryError之前,会去清理只被软引用关联的对象。
  2. 软引用可以与引用队列ReferenceQueue联合使用。当只被软引用关联的对象(即Person对象)被回收后,其相应的包装类对象(即SoftReference对象)会被加入到ReferenceQueue队列中。
  3. 包装类对象被加入到ReferenceQueue队列中后,调用其poll()方法可以获取该队列中的包装类对象。

1.3 弱引用

    public static void weakRef() {
        try {
            Person person = new Person("王五");
            ReferenceQueue<Person> rq = new ReferenceQueue<Person>();
            WeakReference<Person> wr = new WeakReference<Person>(person, rq);
            System.out.println("wr.get():" + wr.get());
            person = null;
            Reference<?> reference;
            while (true) {
                System.out.println("-----");
                reference = rq.poll();
                if (wr.equals(reference)) {
                    System.out.println("wr.get():" + wr.get());
                    System.out.println("被回收了");
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

执行结果:

wr.get():person[王五]
----
----
----
...
wr.get():null
被回收了

解释:
当某个对象只被弱引用关联时,无论内存是否足够,只要 JVM 开始进行垃圾回收,该对象都会被回收。

1.4 虚引用

    public static void phantomRef() {
        Person person = new Person("朱六");
        ReferenceQueue<Person> rq = new ReferenceQueue<>();
        PhantomReference<Person> pr = new PhantomReference<MyTest.Person>(person, rq);
        System.out.println("pr.get():" + pr.get());
        person = null;
        Reference<?> reference;
        while (true) {
            System.out.println("-----");
            reference = rq.poll();
            if (pr.equals(reference)) {
                System.out.println("被回收了");
                break;
            }
        }
    }   

执行结果:

pr.get():null
-----
-----
-----
...
被回收了

解释:

  1. 虚引用必须与引用队列ReferenceQueue联合使用
  2. 虚引用的get()方法永远返回null
  3. 当JVM发现一个对象只被虚引用关联时,则会将虚引用加入ReferenceQueue队列中,然后当JVM垃圾回收时回收该对象

注意:虚引用是先将包装类PhantomReference对象加入ReferenceQueue队列中,然后Person对象才被JVM回收;而软引用和弱引用则相反,是Person对象先被JVM回收,然后才...

2.四种引用的应用场景:

  1. 强引用,不解释。
  2. 软引用,适用于网页、图片、视频等缓存。
    比如app内有一张图片,这张图片很多地方都会用到,如果每次用到的时候都去读取图片,大量的重复读取会导致性能下降,此时可以将图片缓存起来,需要的时候直接从内存中读取,但是由于图片占的内存空间比较大,缓存的图片过多就有可能发生OOM,这时就可以使用软引用。
  3. 弱引用,适用于可能会发生内存泄漏的地方。比如Android中的Handler,参见博客Android Handler详解
  4. 虚引用,在程序中可以判断PhantomReference是否已经被加入ReferenceQueue队列中,如果是,则说明虚引用关联的对象即将被回收,可以在回收之前执行一些必要的业务逻辑。

相关文章

  • Android使用LeakCanary检测内存泄漏

    Java四种引用 在Java中,有四种不同的引用类型,分别是强引用(Strong Reference)、软引用(S...

  • Java中的四种引用类型

    一、Java中的四种引用类型 JDK 1.2 开始 Java 提供了四种引用类型,分别是强引用、软引用、弱引用、虚...

  • java四种引用类型

    java中得四种引用 Java中有四种引用类型:强引用、软引用、弱引用、虚引用 强引用我们代码中常写,如: Obj...

  • JVM虚拟机读书笔记

    Java VM Runtime Area Java中四种引用: - 强引用(Strong Reference): ...

  • RefenceQueue的源码解析,以及WeakHashMap的

    Java RefenceQueue WeakHashMap 首先介绍Java中的四种引用: 强引用:如Object...

  • Java引用及其应用

    Java 引用分类 Java 中的引用分为四种,具体如下 强引用(StrongReference)强引用是使用最普...

  • Java基础:Java的四种引用

    在Java基础:java虚拟机(JVM)中,我们提到了Java的四种引用。包括:强引用,软引用,弱引用,虚引用。这...

  • Java的引用

    参考链接: Java到底是值传递还是引用传递 Java的四种引用方式 Java中的强引用、软引用、弱引用和虚引用 ...

  • Android面试Java基础篇(四)

    问:Java中四种引用类型 答:四种引用类型分别为 强引用、弱引用、软引用、虚引用 强引用(StrongRefer...

  • 深入理解Java弱引用

    Java中的引用类型 Java中存在四种引用,它们由强到弱依次是:强引用、软引用、弱引用、虚引用。下面我们简单介绍...

网友评论

      本文标题:Java中的四种引用

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