【Java】Java的四种引用


学而不思则罔,思而不学则殆
Java有四种引用, 强软弱虚

总结

引用类型type说明
强引用StrongReference最普遍的引用
软引用SoftReference只有在内存不足的时候JVM才会回收该对象
弱引用WeakReference一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存
虚引用PhantomReference

四种引用测试

    private static class TestBean {
        private String name;

        public TestBean(String name) {
            this.name = name;
        }

        @Override
        protected void finalize() throws Throwable {
            super.finalize();
            p("finalize:" + this);
        }

        @Override
        public String toString() {
            return "TestBean{" +
                    "name='" + name + '\'' +
                    '}';
        }
    }

StrongReference

强引用是使用最普遍的引用。只要某个对象有强引用与之关联,JVM不会回收这个对象,即使在内存不足的情况下,JVM宁愿抛出OutOfMemory错误也不会回收这种对象.

        TestBean testBean = new TestBean("强引用对象");
        String str = "强引用对象";
        testBean = null;//testBean 置为null后,就没有引用指向这个对象就可以被JVM回收内存
        str = null;

SoftReference

软引用是用来描述一些有用但并不是必需的对象,在Java中用SoftReference类来表示。只有在内存不足的时候JVM才会回收该对象。

    //测试测试软引用
    private static void testSoftReference() {
        TestBean testBean = new TestBean("Soft1"); //1创建对象“Soft1” ,通过testBean指向该对象 。这是强引用
        ReferenceQueue<TestBean> referenceQueue = new ReferenceQueue<TestBean>(); //2创建引用队列,对象被回收,引用对象会被放进队列中
        SoftReference<TestBean> reference = new SoftReference<TestBean>(testBean, referenceQueue);//3创建testBean对象的软引用
        p("testBean:" + testBean + " reference:" + reference); //打印
        testBean = null; //4 testBean引用置为null, 切断强引用
        System.gc(); //5 触发GC
        System.gc(); //6 触发GC
        TestBean testBean1 = reference.get(); // 7假如testBean对象被回收,testBean1为null
        p("testBean1:" + testBean1); //8打印对象
        Reference ref = referenceQueue.poll(); //9如果testBean对象被回收,这个可以获取reference对象
        p("ref:" + ref);//10打印reference
    }

结果:

testBean:TestBean{name='Soft1'} reference:java.lang.ref.SoftReference@2503dbd3
testBean1:TestBean{name='Soft1'}
ref:null

可以看到,最终没有被回收,这个时候虽然只有软引用指向对象,发生GC的时候,也不一定会被回收掉。
内存模型如下:
在这里插入图片描述
当4执行过后,引用情况如下:
在这里插入图片描述

WeakReference

只具有弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。不过,由于垃圾回收器是一个优先级很低的线程,因此不一定会很快发现那些只具有弱引用的对象。

    //测试弱引用
    private static void testWeakReference() {
        TestBean testBean = new TestBean("Weak1"); //1强引用
        ReferenceQueue<TestBean> referenceQueue = new ReferenceQueue<TestBean>();
        WeakReference<TestBean> reference = new WeakReference<TestBean>(testBean, referenceQueue); //2弱引用
        p("testBean:" + testBean + " reference:" + reference);
        testBean = null; //3切断强应用
        System.gc(); //4 GC
        TestBean testBean1 = reference.get(); // 假如testBean对象被回收,testBean1为null
        p("testBean1:" + testBean1);
        Reference ref = referenceQueue.poll(); //
        p("ref:" + ref);
        if (ref != null) {
            p("ref.get:" + ref.get());
        }
    }

结果:
如果reference 指向的testBean 对象被回收的话,那么系统会把reference 加入到referenceQueue 队列中;可看出reference 被加入到了队列中,说明reference 指向的testBean 对象已经被回收了。

testBean:TestBean{name='Weak1'} reference:java.lang.ref.WeakReference@2503dbd3
testBean1:null    //对象被回收
finalize:TestBean{name='Weak1'}  //finalize方法被执行,该方法会在对象被回收的时候执行
ref:java.lang.ref.WeakReference@2503dbd3   //返回被回收的引用对象
ref.get:null //对象已经被回收了,打印null

模型如下:
在这里插入图片描述
开始的时候,"Weak1"内存区域有两个引用,强引用testBean,和弱引用reference。当切断强引用后,结果如下:
在这里插入图片描述
此时"Weak1"内存区域只有弱引用reference,当发生GC的时候就会被回收掉。

PhantomReference

待定

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值