Java的四种引用方式(强、软、弱、虚引用)

Java的四种引用方式(强、软、弱、虚引用)强引用:java中创建一个对象之后把这个对象赋给一个引用变量,只要强引用在,垃圾收集器永远不会回收,JVM宁愿抛出OutOfMemory错误也不

欢迎大家来到IT世界,在知识的湖畔探索吧!

  • 强引用(StrongReference):java中创建一个对象之后把这个对象赋给一个引用变量,只要强引用在,垃圾收集器永远不会回收,JVM宁愿抛出OutOfMemory错误也不会回收这种对象。具体代码示例:
  • //创建一个用来测试的类
    public class ReferenceDemo {
        private String name;
        private static final int SIZE = 1000;
        private Long[] longArray = new Long[SIZE];
        public ReferenceDemo(String name){
            this.name = name;
        }
        public ReferenceDemo(String name, int size) {
        this.name = name;
        longArray = new Long[size];
    }
    }

    欢迎大家来到IT世界,在知识的湖畔探索吧!

    欢迎大家来到IT世界,在知识的湖畔探索吧!class ReferenceTest{
        public static void main(String[] args) throws InterruptedException {
            System.out.println("start test strongReference");
            ReferenceDemo reference = new ReferenceDemo("strongReference");
            //通过给strongReference赋值,创建一个强引用
            Object strongReference = reference;
            //证明reference和strongReference是同一个对象
            System.out.println(reference == strongReference);
            //给reference赋值为null,也就是说reference变量不指向对象
            reference = null;
            //当把strongReference也指向null时,此时new ReferenceDemo("strongReference");
            //没有任何引用,因此就会被垃圾回收器给回收
            //strongReference = null;
            //手动触发GC
            System.gc();
            Thread.sleep(500);
            //由于对象还存在引用,所以在触发GC后对象未被回收
            System.out.println(strongReference);
            System.out.println("end test strongReference");
        }
    }

    输出结果:

    start test strongReference
    true
    ReferenceDemo@8efb846
    end test strongReference
  • 软引用(SoftReference):一个对象如果具有软引用,并且内存空间足够,垃圾回收器就不会回收它,该对象会尽可能长的保留引用,不会在GC触发时就回收对象,而是直到 JVM 内存不足时才会被回收(虚拟机保证),回收前提是没有关联其他的强引用。这一特性使得 SoftReference 非常适合缓存应用。测试代码如下:
  • 欢迎大家来到IT世界,在知识的湖畔探索吧!class ReferenceTest{
        public static void main(String[] args) throws InterruptedException {
         SoftReference<ReferenceDemo> softReference = new SoftReference<>(new ReferenceDemo("softReference"));
        System.out.println(softReference.get());
        System.gc();
        Thread.sleep(500);
        //即使手动触发后,对象仍然不会被回收
        System.out.println(softReference.get());
        int i = 0;
        while (true) {
            try {
                ++i;
                new ReferenceDemo("oom ", 400_000_000);
            } catch (Throwable e) {
                System.out.println("OOM after " + i + " times");
                e.printStackTrace();
                break;
            }
        }
        //当发生内存溢出时,对象被回收
        System.out.println(softReference.get());
        }
    }

    测试结果:

    com.jinlei.juc.juc.T_001.lock.ReferenceDemo@8efb846
    com.jinlei.juc.juc.T_001.lock.ReferenceDemo@8efb846
    OOM after 1 times
    java.lang.OutOfMemoryError: Java heap space
    	at com.jinlei.juc.juc.T_001.lock.ReferenceDemo.<init>(ReferenceDemo.java:16)
    	at com.jinlei.juc.juc.T_001.lock.ReferenceTest.main(ReferenceDemo.java:49)
    null
  • 弱引用(WeakReference):弱引用是用来描述非必需对象的,当JVM只要进行垃圾回收时,无论内存是否充足,被弱引用关联的对象没有关联其他强引用时,都会被回收。weakHashMap就是实现之一。测试代码如下:
  • class ReferenceTest {
        public static void main(String[] args) throws InterruptedException {
            System.out.println("start test weakReference");
            //创建一个弱引用对象
            WeakReference<ReferenceDemo> weakReference = new WeakReference<>(new ReferenceDemo("weakReference"));
            System.out.println(weakReference.get());
            //ReferenceDemo strongReference = weakReference.get();    7
            //手动触发GC
            System.gc();
            Thread.sleep(500);
            System.out.println(weakReference.get());
            System.out.println("end test weakReference");
        }
    }

    测试结果:

    start test weakReference
    com.jinlei.juc.juc.T_001.lock.ReferenceDemo@8efb846
    null
    end test weakReference

    当有强引用,第7行代码打开时,对象是不会被回收的:

    start test weakReference
    com.jinlei.juc.juc.T_001.lock.ReferenceDemo@8efb846
    com.jinlei.juc.juc.T_001.lock.ReferenceDemo@8efb846
    end test weakReference
  • 虚引用(PhantomReference):虚引用和前面的软引用、弱引用不同,它并不影响对象的生命周期。在java中用java.lang.ref.PhantomReference类表示。如果一个对象与虚引用关联,则跟没有引用与之关联一样,在任何时候都可能被垃圾回收器回收,因为它的get() 方法永远返回 null, 这也正是它名字的由来。要注意的是,虚引用必须和引用队列关联使用,当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会把这个虚引用加入到与之关联的引用队列中。程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。如果程序发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。虚引用主要用于检测对象是否已经从内存中删除。
  • //创建一个引用队列
    ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();
    //创建一个虚引用
    PhantomReference<ReferenceDemo> phantomReference = new PhantomReference<>(new ReferenceDemo("phantomReference"),referenceQueue);
    //虚引用的get方法永远返回为null
    System.out.println(phantomReference.get());
    System.out.println(referenceQueue.poll());
    System.gc();
    Thread.sleep(500);
    System.out.println(referenceQueue.poll());

    测试结果如下:

    null
    null
    java.lang.ref.PhantomReference@8efb846

    免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/36861.html

    (0)

    相关推荐

    发表回复

    您的邮箱地址不会被公开。 必填项已用 * 标注

    联系我们YX

    mu99908888

    在线咨询: 微信交谈

    邮件:itzsgw@126.com

    工作时间:时刻准备着!

    关注微信