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

软引用和弱引用的区别_强引用软引用弱引用虚引用的区别示例代码: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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 上海java培训哪家教育机构比较好_上海it培训机构排名前十

    上海java培训哪家教育机构比较好_上海it培训机构排名前十学习Java编程不在是校内学生们的专利了,随着职场上竞争越来越激烈,毫无基础的或想要转行的求职者对于学习Java的积极性也是越来越高,因此,市面上涌现了大批的成人Java培训机构,为了不让大家纠结,小编花费了一周时间给大家专门整理了上海Java培训机构排名榜单,主要从口碑,师资,专一性,就业率等多方面得出的上海Java培训机构排名,仅供正在选择Java培训机构的小伙们参考。1.上海动力节点评价:动力节点大家学Java的话肯定也都听说过,单科教学,一直是秉承着从学员角度,全心全意保障学员利益.

    2022年10月3日
    2
  • navicat15永久激活码最新【2021.7最新】「建议收藏」

    (navicat15永久激活码最新)本文适用于JetBrains家族所有ide,包括IntelliJidea,phpstorm,webstorm,pycharm,datagrip等。IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.html…

    2022年3月21日
    513
  • dao层和service层和control代码(Java简述抽象类和接口的区别)

    DAO层:DAO层叫数据访问层,全称为dataaccessobject,属于一种比较底层,比较基础的操作,具体到对于某个表的增删改查,也就是说某个DAO一定是和数据库的某一张表一一对应的,其中封装了增删改查基本操作,建议DAO只做原子操作,增删改查。Service层:Service层叫服务层,被称为服务,粗略的理解就是对一个或多个DAO进行的再次封装,封装成一个服务,所以这里也就不…

    2022年4月18日
    59
  • JDK开发环境搭建及环境变量配置(win10)

    JDK开发环境搭建及环境变量配置(win10)安装JDK开发环境网址:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html要首先点击AcceptLicenseAgreement,然后下载系统对应的版本,我下载的为Windowsx64打开下载下来的可执行文件点击下一步安装位置自行设置,当提示安…

    2022年7月21日
    12
  • 不借助任何工具将CLOVER引导添加进UEFI的正确姿势(简单暴力版本)「建议收藏」

      经常安装hackintosh的同学会发现,安装完macOS后,需要做的第一件事情就要将EFI移进机器自带的磁盘中,同时添加CLOVER引导项到UEFI中以实现CLOVER引导加载macOS。通常的作法是进Windows/PE工具里,使用类似EASYUEFI或者BOOTICE之类的工具添加一条引导记录到UEFI中。现在教给大家一招:不借助任何工具,使用CLOVER自带的功能添加一个…

    2022年4月8日
    70
  • 使用MATLAB绘制分段函数实现[通俗易懂]

    使用MATLAB绘制分段函数实现[通俗易懂]绘制分段函数也是很常见的需求,实现分段函数的绘制也有多种方式。以下面分段函数为例,进行说明。方法一:直接根据分段函数的含义,根据x值的不同,相对应的函数值也不同,进行描点连线。x=0:0.1:5y=[]forxx=xif(xx<1.5)y=[y,0];elseif(xx>=1.5&&xx<2)y=[y,(xx-1.5)*2];elsey=[y,1];endendplot(x,y)%函数图像上加一

    2022年6月12日
    33

发表回复

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

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