软引用和弱引用的区别_强引用软引用弱引用虚引用的区别

软引用和弱引用的区别_强引用软引用弱引用虚引用的区别示例代码:importjava.lang.ref.SoftReference;/***@authorchenjc*@since2020-01-13*/publicclassSoftReferenceTest{/***使用JVM参数-Xmx10m运行程序**@paramargs*@throwsI…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

示例代码:

import java.lang.ref.SoftReference;

/** * @author chenjc * @since 2020-01-13 */
public class SoftReferenceTest { 
   

    /** * 使用JVM参数-Xmx10m运行程序 * * @param args * @throws InterruptedException */
    public static void main(String[] args) throws InterruptedException { 
   
        User user = new User(1, "debo");
        // 建立User对象的软引用
        SoftReference<User> userSoftReference = new SoftReference<>(user);
        // 去掉强引用
        user = null;
        System.out.println(userSoftReference.get());
        // 手动触发GC
        System.gc();
        System.out.println("第一次GC: " + userSoftReference.get());
        // 分配适量内存空间,造成内存资源紧张,产生GC,同时又不会导致堆内存溢出
        byte[] bytes = new byte[6 * 1024 * 1050];
        System.out.println("第二次GC: " + userSoftReference.get());
    }

    private static class User { 
   
        private Integer id;
        private String name;

        public User(Integer id, String name) { 
   
            this.id = id;
            this.name = name;
        }

        public Integer getId() { 
   
            return id;
        }

        public void setId(Integer id) { 
   
            this.id = id;
        }

        public String getName() { 
   
            return name;
        }

        public void setName(String name) { 
   
            this.name = name;
        }

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

使用JVM参数-Xmx10m运行此程序,输出如下:

User{id=1, name='debo'}
第一次GC: User{id=1, name='debo'}
第二次GC: null

第一次GC的时候,软引用没有被回收,是因为这时候内存资源充足。第二次由于分配了较大的内存,导致GC,这时候由于内存资源紧张,软引用被回收了,也就是虽然User对象有一个软引用在引用着它,但User对象在此条件下也会被GC回收。所以软引用的对象在一定条件下可被回收,故软引用对象不会导致内存溢出。

软引用到底有没有被回收,可以通过给软引用一个ReferenceQueue来跟踪,将上面的代码片段稍作修改,如下:

import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;

/** * @author chenjc * @since 2020-01-13 */
public class SoftReferenceTest { 
   

    /** * 使用JVM参数-Xmx10m运行程序 * * @param args * @throws InterruptedException */
    public static void main(String[] args) throws InterruptedException { 
   
        User user = new User(1, "debo");
        // 建立User对象的软引用
        ReferenceQueue<User> userReferenceQueue = new ReferenceQueue<>();
        UserSoftReference userSoftReference = new UserSoftReference(user, userReferenceQueue);
        // 去掉强引用
        user = null;
        System.out.println(userSoftReference.get());
        // 手动触发GC
        System.gc();
        System.out.println("第一次GC: " + userSoftReference.get());
        System.out.println("第一次GC队列: " + userReferenceQueue.remove(1000));
        // 分配适量内存空间,造成内存资源紧张,产生GC,同时又不会导致堆内存溢出
        byte[] bytes = new byte[6 * 1024 * 1055];
        System.out.println("第二次GC: " + userSoftReference.get());
        Reference<? extends User> reference = userReferenceQueue.remove(1000);
        if (reference != null) { 
   
            UserSoftReference userSoftReference1 = (UserSoftReference) reference;
            System.out.println("第二次GC队列: " + userSoftReference1.getId());
        }
    }

    private static class User { 
   
        private Integer id;
        private String name;

        public User(Integer id, String name) { 
   
            this.id = id;
            this.name = name;
        }

        public Integer getId() { 
   
            return id;
        }

        public void setId(Integer id) { 
   
            this.id = id;
        }

        public String getName() { 
   
            return name;
        }

        public void setName(String name) { 
   
            this.name = name;
        }

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

    private static class UserSoftReference extends SoftReference<User> { 
   

        private Integer id;

        public UserSoftReference(User referent, ReferenceQueue<? super User> q) { 
   
            super(referent, q);
            this.id = referent.id;
        }

        public Integer getId() { 
   
            return id;
        }

        public void setId(Integer id) { 
   
            this.id = id;
        }
    }
}

输出如下:

User{id=1, name='debo'}
第一次GC: User{id=1, name='debo'}
第一次GC队列: null
第二次GC: null
第二次GC队列: 1

第一次GC没有回收软引用对象,所以ReferenceQueue为空,第二次GC回收了软引用对象,所以ReferenceQueue队列不为空,那为什么可以强转成UserSoftReference呢?是因为队列里面的reference就是方法局部变量userSoftReference。此处自定义一个UserSoftReference类主要是为了跟踪User对象的id,你无法跟踪User对象,因为User对象已经被回收了,如果调用reference.get(),将会返回null。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/195980.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Android源码学习之环境搭建(Ubuntu下载Android源码)

    Android源码学习之环境搭建(Ubuntu下载Android源码)已经有一个多月没有看Android的知识了,之前在杭州时就买了邓凡平的《深入理解Android卷I》一直没来得及研究。后来因为公司要求,要为新的项目做准备,做各种业务的KT和技术的training,虽然新技术本身的难度不大,但是业务知识很是复杂,搞的头大,到现在终于有了一些头绪。趁现在有时间来研究下Android的源码。之前没有接触过Linux系统,我的本本现在用的是Windows系统,已经用习

    2022年5月6日
    38
  • 上海十大it外包公司[通俗易懂]

    上海十大it外包公司[通俗易懂]1.中软国际(北京)2.东软集团Neusoft(沈阳)3.博彦科技BeyondSoft(北京)4.图灵方舟www.tlio.cn(河北)5.海辉软件HiSoft(大连)6.文思VanceInfo(北京)7.浙大网新Insigma(杭州)9.软通动力(北京)8.柯莱特(北京)10.浪潮Inspur(济南)…

    2022年6月9日
    158
  • warning: #1300-D: XXX inherits implicit virtual 报警

    warning: #1300-D: XXX inherits implicit virtual 报警在KeilMDK里使用了C++,其中用到了基类和派生类。编译的时候出现了大量warning: #1300-D:XX_function inheritsimplicitvirtual的警告信息。由于对C++不熟,花了好半天时间去找消除警告信息的方法。后面发现是这样的。在基类中,定义了虚成员函数。如下:classDriver{public:virtual…

    2025年6月2日
    0
  • 微机原理考试试题及答案分析_微机原理及接口技术

    微机原理考试试题及答案分析_微机原理及接口技术微机原理与接口技术期末考试试题及答案微机原理与接口技术期末考试题库微机系统的硬件由哪几部分组成?答:三部分:微型计算机(微处理器,存储器,I/0接口,系统总线),外围设备,电源。什么是微机的总线,分为哪三组?答:是传递信息的一组公用导线。分三组:地址总线,数据总线,控制总线。8086/8088CPU的内部结构分为哪两大模块,各自的主要功能是什么?答:总线接口部件(BIU)功能:根据执行单元EU的…

    2022年9月1日
    2
  • 清华大学团队:人脸识别爆出巨大丑闻,15分钟解锁19款手机

    清华大学团队:人脸识别爆出巨大丑闻,15分钟解锁19款手机1清华大学的RealAI团队15分钟解锁19款手机刚刚,清华大学的一条重大发现,利用人脸识别技术的漏洞,“15分钟解锁19个陌生智能国产手机”的事件,引发无数网友关注。据悉,清华大学的RealAI团队共选取了20款手机,其中1款是国外的,另外19款都是我们国产的智能手机,居来自排名前五的国产手机品牌,每一品牌下选取了3-4款不同价位的手机型号,覆盖低端机到旗舰机。1)测试步骤如下:第一步,清华大学的测试人员,把19部国产手机,人脸识别全部绑定为旁边的“1号同学”;

    2022年6月5日
    139
  • 交叉线 与 直通线

    交叉线 与 直通线交叉线  交叉线:又叫反线,线序按照一端568B,一端568A的标准排列好线序,并用RJ45水晶头夹好。      具体的线序制作方法是:一端采用568B(即白橙,橙,白绿,蓝,白蓝,绿,白棕,棕的顺序)做线标准不变,另一端在这个基础上将这八根线中的1,3号线和2,6号线互换一下位置,这时网线的线序就变成了:1、白绿、2、绿、3、白橙、4、蓝、5、白蓝、6、橙、7、白棕、8、棕(即正线的1,

    2022年6月19日
    22

发表回复

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

关注全栈程序员社区公众号