系列十二、强引用、软引用、弱引用、虚引用分别是什么?

一、整体架构

二、强引用(默认支持模式)

2.1、概述

        当内存不足时,JVM开始垃圾回收,对于强引用的对象,就算是出现了OOM也不会对该对象进行回收,死都不收。

        强引用是我们最常见的普通对象引用,只要还有强引用指向另一个对象,就表明该对象还"活着",垃圾收集器不会回收这种对象。在Java中最常见的就是强引用,把一个对象赋给一个

一个引用变量,这个引用变量就是一个强引用。当一个对象被强引用变量引用时,它处于可达状态,它是不可能被垃圾回收器回收的,即使该对象永远都不会被JVM回收。因此强引用是造成Java内存泄露的主要原因之一。

        对于一个普通的对象,如果没有其他的引用关系,只要超过了引用的作用域或者显示地将强引用赋值为null,一般认为就是可被垃圾收集器收集的了。(具体回收时机还是要看垃圾收集策略)。

2.2、案例代码

/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/11/19 18:13
 * @Description: 强引用案例演示
 */
public class StrongReferenceMainApp {

    public static void main(String[] args) {
        // 这样定义的默认就是强引用
        Object o1 = new Object();

        // o2引用赋值
        Object o2 = o1;

        // o1置空
        o1 = null;

        System.gc();
        System.out.println(o2);
        System.out.println(o1 == null);
        System.out.println(o2 == null);
    }

}

三、软引用

3.1、概述

        软引用是一种相对强引用弱化了一些的引用,需要用java.lang.ref.SoftReference类来实现,可以让对象豁免一些垃圾收集。

        对于只有弱引用的对象来说:

                当系统内存充足时,不会被回收;

                当系统内存不足时,会被回收;

        软引用通常用在对内存敏感的程序中,比如高速缓存就有用到软引用,内存够用的时候就保留,不够用就回收!

3.2、案例代码

/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/11/19 18:13
 * @Description: 软引用案例演示
 */
public class SoftReferenceMainApp {

    public static void main(String[] args) {
        Object o1 = new Object();
        SoftReference<Object> softReference = new SoftReference<>(o1);
        System.out.println(o1);
        System.out.println(softReference.get());

        o1 = null;
        System.gc();

        System.out.println(o1);
        System.out.println(softReference.get());

    }

}

四、弱引用

4.1、概述

        弱引用需要使用java.lang.ref.WeakReference类来实现,它比软引用的生存期更短。

        

        对于只有弱引用的对象来说,只要垃圾回收机制一运行,不管JVM的内存是否足够,都会回收该对象占用的内存;

4.2、案例代码

/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/11/19 18:13
 * @Description: 弱引用案例演示
 */
public class WeakReferenceMainApp {

    public static void main(String[] args) {
        Object o1 = new Object();
        WeakReference<Object> weakReference = new WeakReference<>(o1);
        System.out.println(o1);
        System.out.println(weakReference.get());

        o1 = null;
        System.gc();

        System.out.println(o1);
        System.out.println(weakReference.get());

    }

}

4.3、软引用和弱引用的适用场景

假设有一个应用需要读取大量的本地图片:

        如果每次读取图片都从硬盘读取,则会严重影响性能;

        如果一次性全部加载大内存中,又有可能造成内存溢出;

        此时,可以使用软引用来解决这个问题,思路如下:

        用一个HashMap来保存图片的路径和相应图片对象关联的弱引用之间的映射关系,当内存不足时,JVM自动回收这些缓存图片对象所占用的空间,从而有效的避免OOM的问题。

        Map<String,SoftReference<Bitmap>> imageCache = new HashMap<String,SoftReference<Bitmap>>();

4.4、你知道弱引用的话,能谈谈WeakHashMap吗

/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/11/19 18:44
 * @Description: 你知道弱引用,能谈谈WeakHashMap吗?
 */
public class WeakHashMapMainApp {

    public static void main(String[] args) {
        WeakHashMap<Integer, String> map = new WeakHashMap<>();
        Integer key = new Integer(2);
        String value = "weakHashMap";

        map.put(key, value);
        System.out.println(map);

        key = null;
        System.out.println(map);

        System.gc();
        System.out.println(map + "\t" + map.size());

    }

}

五、虚引用 

5.1、概述

        虚引用需要java.lang.ref.PhantomReference类来实现。

        顾名思义,虚引用就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾收集器回收,它不能单独使用也不能通过它来访问对象,虚引用必须和引用队列(ReferenceQueue)联合使用。

        虚引用的主要作用是用来跟踪对象被垃圾回收的状态。仅仅是提供了一种确保对象被finalize以后,做某些事情的机制。

        PhantomReference的get()总是返回null,因此无法访问对应的引用对象。其意义在于说明一个对象已经进入finalization阶段,可以被gc回收,用来实现比finalization机制更灵活的回收操作。

        换句话说,设置虚引用关联的唯一目的就是在这个对象被收集器回收的时候,收到一个系统通知或者后续执行进一步的处理。

        Java技术允许使用finalize()方法在垃圾收集器将对象从内存中清除之前做必要的清理工作。

5.2、引用队列

5.3、案例代码

/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/11/19 19:10
 * @Description: 虚引用案例代码
 */
public class PhantomReferenceMainApp {

    public static void main(String[] args) {
        Object o1 = new Object();
        ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();
        PhantomReference<Object> phantomReference = new PhantomReference<>(o1,referenceQueue);

        System.out.println(o1);
        System.out.println(phantomReference.get());
        System.out.println(referenceQueue.poll());
    }

}

六、GCRoot和四大引用小总结

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/165162.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

特效!视频里的特效在哪制作——Adobe After Effects

今天&#xff0c;我们来谈谈一款在Adobe系列中推出的一款图形视频处理软件&#xff0c;适用于从事设计和视频特技的机构&#xff0c;包括电视台、动画制作公司、个人后期制作工作室以及多媒体工作室的属于层类型后期软件——Adobe After Effects。 Adobe After Effects&#xf…

苍穹外卖项目笔记(3)——员工管理

前言 这些功能都没有展示对应的测试结果&#xff0c;可自行通过接口文档进行测试&#xff0c;也可以进行前后端联调测试&#xff0c;附代码链接&#xff1a;take-out 1新增员工 1.1 需求分析和设计 产品原型 接口设计 【注】code&#xff1a;操作成功返回1&#xff0c;否则…

Azure Machine Learning - Azure AI 搜索中的集成数据分块和嵌入

在基于索引器的索引编制中&#xff0c;Azure AI _集成矢量化_将数据分块和文本到矢量嵌入添加到技能中&#xff0c;它还为查询添加文本到矢量的转换。 关注TechLead&#xff0c;分享AI全维度知识。作者拥有10年互联网服务架构、AI产品研发经验、团队管理经验&#xff0c;同济本…

我叫:选择排序【JAVA】

1.我是个啥子&#xff1f;&#xff1f; 选择式排序&#xff1a;属于内部排序法,从欲排序的数据中,按指定的规则选出某一元素&#xff0c;再依规定交换位置后达到排序的目的。 2.我的思想 基本思想:第一次从arr[0]~arr[n-1]中选取最小值&#xff0c;与arr[0]交换&#xff0c;第…

io多路复用:select、poll和epoll

1、为什么使用多路复用&#xff1a; 1.1单线程BIO监听socket 多路复用一般用于网络io当中&#xff0c;提到网络io我们肯定能想到socket。如果我们想要一个线程单纯的用向下文的方式监听很多个socket看他是否有事件发生&#xff0c;那这样是不可行。 但上一个socket1没有可读事…

哪个电脑录屏软件好用又免费?十大好用的免费录屏软件排行

屏幕录制软件是一个非常有用的辅助工具&#xff0c;可以帮助您录制屏幕上的所有内容&#xff0c;并根据需要将其转换为视频。 此外&#xff0c;免费的屏幕录像机可以为您节省大量不必要的费用。在这篇文章中&#xff0c;我将列出我在工作和学习中最有效使用的 10 个软件。 每…

OSG加载模型时显示读取进度

目录 1. 前言 2. 开发环境说明 3. 功能实现 3.1. 方法1 3.2. 方法2 3.3. 方法3 4. 附加说明 1. 前言 OSG中加载模型文件到视景器&#xff0c;一般通过osgDB::readXXXX系列开头的函数来加载模型&#xff0c;如&#xff1a;osgDB::readNodeFile、osgDB::readImageFile、os…

Pytest自动化测试框架:mark用法---测试用例分组执行

pytest中的mark&#xff1a; mark主要用于在测试用例/测试类中给用例打标记(只能使用已注册的标记名)&#xff0c;实现测试分组功能&#xff0c;并能和其它插件配合设置测试方法执行顺序等。 如下图&#xff0c;现在需要只执行红色部分的测试方法&#xff0c;其它方法不执行&am…

【精选】项目管理工具——Maven详解

Maven简介 Maven是一个项目管理工具。它可以帮助程序员构建工程&#xff0c;管理jar包&#xff0c;编译代码&#xff0c;完成测试&#xff0c;项目打包等等。 Maven工具是基于POM&#xff08;Project Object Model&#xff0c;项目对象模型&#xff09;实现的。在Maven的管理下…

【React】React 基础

1. 搭建环境 npx create-react-app react-basic-demo2. 基本使用 JSX 中使用 {} 识别 JavaScript 中的表达式&#xff0c;比如变量、函数调用、方法调用等。 if、switch、变量声明等属于语句&#xff0c;不是表达式。 列表渲染使用 map 。 事件绑定用&#xff1b;on 事件名称…

公寓水电管理系统

springbootmybatisthymeleaf 这次练习是尝试将layer与系统结合起来&#xff0c;将新增、修改、删除都和弹窗结合起来。 一、需求分析 二、数据库 三、模块 1、登录页面 哈哈哈&#xff0c;之前做的登录页面都好丑&#xff0c;这是目前做的最好看的一次了。 超级管理员&…

Java 教育局民办教育信息服务与监管平台

1) 项目背景 按照《中华人民共和国民办教育促进法》和《中华人民共和国政府信息公开条例》的相关规定&#xff0c;为满足学生和家长、社会各界获取权威信息的需求&#xff0c;着力解决服务老百姓最后一公里问题&#xff0c;达到宣传民办教育和引导家长择校的效果&#xff0…

Java实现图书管理系统

今天与大家分享的是一个图书管理系统&#xff0c;这里我们运用的是java基础的语法其中包括类和对象、继承、封装、多态、抽象类、接口还有数组等。 我们需要实现一个可以进行管理员操作和用户操作的图书管理系统&#xff0c;其中包括了管理员操作(查找&#xff0c;添加&#x…

SpringBoot中日志的使用log4j

SpringBoot中日志的使用log4j 项目中日志系统是必不可少的&#xff0c;目前比较流行的日志框架有 log4j、logback 等&#xff0c;这两个框架的作者是同一个 人&#xff0c;Logback 旨在作为流行的 log4j 项目的后续版本&#xff0c;从而恢复 log4j 离开的位置。 另外 slf4j(…

定点整数、小数

文章目录 一、定点整数二、定点小数三、定点小数的加/减运算 一、定点整数 二、定点小数 三、定点小数的加/减运算 对两个定点小数A、B进行加法/减法时&#xff0c;需要先转换为补码 计算机硬件如何做定点小数补码的加法&#xff1a;从最低位开始&#xff0c;按位相加&#x…

栈与队列:设计循环队列

目录 题目&#x1f525;&#xff1a; 数据模型&#xff1a; 本题大意&#xff1a; 思路分析&#xff1a; 代码分析&#xff1a; 一、定义队列 二、初始化、判断队列的空和满⭐ 初始化&#xff1a; 空满的判断&#xff1a; 三、入队和出队&#x1f387; 入队&…

Vue中实现div的任意移动

前言 在系统应用中&#xff0c;像图片&#xff0c;流程预览及打印预览等情况&#xff0c;当前视窗无法全部显示要预览的全部内容&#xff0c;设置左右和上下滚动条后&#xff0c;如果用鼠标拖动滚动条&#xff0c;又不太便利&#xff0c;如何用鼠标随意的移动呢&#xff1f; …

前端面试:如何实现并发请求数量控制?

题目&#xff1a;实现一个并发请求函数concurrencyRequest(urls, maxNum) 要求如下&#xff1a; 要求最大并发数 maxNum;每当有一个请求返回&#xff0c;就留下一个空位&#xff0c;可以增加新的请求;所有请求完成后&#xff0c;结果按照 urls 里面的顺序依次打出&#xff1b;…

.babyk勒索病毒解析:恶意更新如何威胁您的数据安全

导言&#xff1a; 在数字时代&#xff0c;威胁不断进化&#xff0c;其中之一就是.babyk勒索病毒。这种病毒采用高级加密算法&#xff0c;将用户文件锁定&#xff0c;并要求支付赎金以获取解密密钥。本文91数据恢复将深入介绍.babyk勒索病毒的特点、如何应对被加密的数据&#…

【Promise12数据集】Promise12数据集介绍和预处理

【Segment Anything Model】做分割的专栏链接&#xff0c;欢迎来学习。 【博主微信】cvxiayixiao 本专栏为公开数据集的介绍和预处理&#xff0c;持续更新中。 要是只想把Promise12数据集的raw形式分割为png形式&#xff0c;快速导航&#xff0c;直接看2&#xff0c;4标题即可 …
最新文章