JVM虚拟机(五)强引用、软引用、弱引用、虚引用

目录

    • 一、强引用
    • 二、软引用
    • 三、弱引用
    • 四、虚引用
    • 五、总结

引文:

在 Java 中一共存在 4 种引用:强、软、弱、虚。它们主要指的是,在进行垃圾回收的时候,对于不同的引用垃圾回收的情况是不一样的。下面我们就一起来看一下这 4 种引用。

一、强引用

强引用:只有所有 GC Root 对象都不通过【强引用】引用该对象,该对象才能被垃圾回收。

强引用是比较常见的,比如说下面这段代码种,这个 user 就是强引用:

User user = new User();

强引用的特点有哪些呢?如下图所示:

现在有一个 GC Root,我们之前讲过 GC Root 是用来定位哪些对象是存活的。

  • 假如说 GC Root 关联到了 User 对象,那就证明这个 User 对象是存活的,则这个 User 对象一直都不会被垃圾回收,即使出现了内存不足,抛出 OOM 异常,也不会回收强引用的对象。
  • 只有当 GC Root 不再关联 User 对象,那这个对象才有可能会被垃圾回收器进行回收。

以上就是强引用的特点。


二、软引用

软引用:仅有软引用引用该对象时,在垃圾回收后,内存仍不足时会再次触发垃圾回收。

我们先来看一段代码:

User user = new User();
SoftReference softReference = new SoftReference(user);

在这段代码中,我们先创建了一个 User 对象,然后又创建了一个 SoftReference 对象并且包装了 User 对象。它们的关系如下图所示:

首先 GC Root 能够关联到 SoftReference 对象,然后当前的 SoftReference 又会关联 User 对象。大家注意,SoftReference 对象和 User 对象之间的关联是使用的虚线,因为这种关联属于软引用。

在进行垃圾回收的时候,一开始并不会对 user 对象进行垃圾回收。由于 user 对象是一个软引用,如果在第一次垃圾回收之后内存还是不够,马上又进行了一次垃圾回收,这个时候软引用 User 对象就会被垃圾回收器回收了。

以上就是软引用的介绍,它必须配合 SoftReference 进行使用。


三、弱引用

弱引用:仅有弱引用引用该对象时,在垃圾回收的时候,无论内存是否充足,都会回收弱引用对象。

弱引用和软引用的使用有些类似,我们来看这样一段代码:

User user = new User();
WeakReference weakReference = new WeakReference(user);

在这段代码中,先创建了一个 User 对象,然后创建了一个 WeakReference 对象并且包装了 User 对象,他们的关系如下图所示:

首先,GC Root 关联到的是 WeakReference 对象,然后由 WeakReference 对象去关联了 User 对象,这里也是用虚线表示的。目前这个 User 对象就是一个弱引用。

在进行垃圾回收的时候。一旦内存不够用了,User 对象作为一个弱引用对象,就会被垃圾回收器回收掉。

关于弱引用有一个经典的例子,就是 ThreaLocal 内存泄露的问题

在这里插入图片描述

在 ThreadLocal 中有一个 Entry 对象,它继承了 WeakReference,然后在构造函数里面调用了 super(k) 方法,也就表示了当前构造函数中的 ThreadLocal<?> 是一个弱引用,一旦内存不够的时候进行了垃圾回收,就会把 k 对象回收掉。但是 value 使用的是 = 进行赋值,就是一个强引用,并不会被垃圾回收器进行回收。所以说这块儿就可能产生内存泄漏。

以上就是弱引用的说明。


四、虚引用

虚引用:必须配合引用队列使用,被引用对象回收时,会将虚引用入队,由 Reference Handler 线程调用虚引用相关方法释放直接内存。

为了方便理解,我们来看这样一段代码:

User user = new User();
ReferenceQueue referenceQueue = new ReferenceQueue();
PhantomReference phantomReference = new PhantomReference(user, referenceQueue);

在这段代码中,先创建了一个 User 对象,然后创建了一个 ReferenceQueue 对象(就是一个引用队列),最后创建了一个 PhantomReference 对象并且包装了 User 对象和 ReferenceQueue 对象。它们之间的关系如下图所示:

在这里插入图片描述

首先,GC Root 直接关联的是 PhantomReference 虚引用对象,一个是 X,另一个是 Y。这两个 PhantomReference 对象分别去引用了 User1 对象和 User2 对象。

大家可能会想,这里面哪里能体现 ReferenceQueue 队列呢?是这样的,将来如果发生了垃圾回收,把 User1 和 User2 这两个对象回收掉了,那么 PhantomReference 虚引用对象本身在进行垃圾回收发生的时候,会把虚引用对象 X 和 Y 加入到 ReferenceQueue 引用队列中,如下图所示:

在这里插入图片描述

把 X 和 Y 虚引用对象加入到 ReferenceQueue 引用队列中之后,引用队列就会配合 Reference Handler 这个线程来去释放虚引用对象所关联的一些外部资源。

比如说 User1 和 User2 已经被垃圾回收掉了,但是回收这两个对象只是释放了 Java 的堆内存资源,它们在使用的过程中有可能会使用一些外部的资源,这些外部资源有可能不是 Java 的内存,有可能使用的是系统的直接内存,那这些内存什么时候释放呢?这些内存必须要等 Java 对象回收掉之后,才能去释放这些外部的资源内存。所以说就需要把这些虚引用对象放入到引用队列中,先记录哪些对象被回收了,然后由 Reference Handler 根据队列的内容去回收资源就可以了。比如我们示例中的 X 和 Y 两个虚引用对象,它们关联的 User 对象已经被回收掉了,这个时候我们也应该把 X 和 Y 对应的外部资源进行释放,有一个专门的线程来进行释放,就叫 Reference Handler。它就会去从引用队列中不断地把这些虚引用对象 X 和 Y 取出来,然后把它们占用的外部资源进行释放。

以上就是虚引用对象的说明了,它需要配合 ReferenceQueue 引用队列才能使用。

补充: 软引用和弱引用也可以通过引用队列去释放自身的资源。

下面我们总结一下这四种引用类型。


五、总结

强引用、软引用、弱引用、虚引用的区别?

  • 强引用:比较常见,只要 GC Root 能关联到,就不会被回收。
  • 软引用:需要配合 SoftReference 使用,当垃圾被多次回收,内存依然不够的时候会回收软引用对象。
  • 弱引用:需要配合 WeakReference 使用,只要进行了垃圾回收,就会把弱引用对象回收。
  • 虚引用:必须配合引用队列使用,被引用对象回收时,会将虚引用入队,由 Reference Handler 线程调用虚引用相关方法释放直接内存等外部资源。

整理完毕,完结撒花~🌻

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于R语言实现的负二项回归模型【理解与实现】-理解负二项回归模型和泊松回归模型之间的区别

前言 我们可以在R语言中使用MASS包中的glm.nb函数来拟合负二项模型&#xff0c;以及使用glm函数来拟合泊松模型。以下是一个详细的过程&#xff0c;包括模拟数据的生成、模型的拟合、结果的比较和解释。 需要的包 if (!require("MASS")) install.packages("M…

Linux网络基础 (二) ——(IP、MAC、端口号、TCPUDP协议、网络字节序)

文章目录 IP 地址基本概念源IP地址 & 目的IP地址 MAC 地址基本概念源MAC地址 & 目的MAC地址 端口号基本概念源端口号 & 目的端口号 TCP & UDP 协议基本概念TCP 与 UDP 的抉择 网络字节序大端、小端字节序 &#x1f396; 博主的CSDN主页&#xff1a;Ryan.Alask…

YOLOv8模型剪枝实战:DepGraph(依赖图)方法

课程链接&#xff1a;YOLOv8模型剪枝实战&#xff1a;DepGraph(依赖图)方法_在线视频教程-CSDN程序员研修院 YOLOv8是一个当前非常流行的目标检测器&#xff0c;本课程使用DepGraph&#xff08;依赖图&#xff09;剪枝方法对YOLOv8进行网络剪枝&#xff0c;使其更加轻量和实用…

Qt快速入门(MV架构之TableView + QStandardItemModel + 自定义代理小案例)

Qt快速入门&#xff08;MV架构之TableView QStandardItemModel 自定义代理小案例&#xff09; 关于MV架构的简单介绍 在Qt框架中&#xff0c;代理&#xff08;Delegate&#xff09;、模型&#xff08;Model&#xff09;和视图&#xff08;View&#xff09;之间的关系构成了…

51单片机实验03-单片机定时/计数器实验

目录 一、实验目的 二、实验说明 1、51单片机有两个16位内部计数器/定时器&#xff08;C/T&#xff0c; Counter/Timer&#xff09;。 2、模式寄存器TMOD 1) M1M0工作模式控制位&#xff1b; 2) C/T定时器或计数器选择位&#xff1a; 3&#xff09;GATE定时器/计数器运行…

Python零基础从小白打怪升级中~~~~~~~模块+异常+Pycharm的debug调试

第十节&#xff1a;模块异常Debug 一、Python模块 Python 模块(Module)&#xff0c;是一个 Python 文件&#xff0c;以 .py 结尾&#xff0c;模块能定义函数&#xff0c;类和变量&#xff0c;模块里也能包含可执行的代码。 1、导入模块 导入模块的5中方式 import 模块名fr…

C++ 之 【类与对象】从入门到精通一条龙服务 最终篇(static成员、友元、匿名对象。。。)

&#x1f4b4;到用时方恨早&#xff0c;白首方悔挣的少 车到山前没有路&#xff0c;悬崖勒马勒不住 一、再谈构造函数 1.构造函数体赋值 2.初始化列表 3.explicit关键字 二、Static成员 1.概念 2.特性 三、友元 1.友元函数 2.友元类 四、内部类 五、匿名对象 六、…

结合 tensorflow.js 、opencv.js 与 Ant Design 创建美观且高性能的人脸动捕组件并发布到InsCode

系列文章目录 如何在前端项目中使用opencv.js | opencv.js入门如何使用tensorflow.js实现面部特征点检测tensorflow.js 如何从 public 路径加载人脸特征点检测模型tensorflow.js 如何使用opencv.js通过面部特征点估算脸部姿态并绘制示意图tensorflow.js 使用 opencv.js 将人脸…

模型预测控制MPC(1)—— 基础概念

文章目录 1. 历史沿革1.1 控制论1.2 最优控制与强化学习 2. 模型预测控制 1. 历史沿革 我本科做机器人的时候接触过一点控制&#xff0c;主要做了大量 PID 在嵌入式控制系统的应用&#xff1b;硕士期间研究方向是强化学习。在我调研 MPC 的过程中&#xff0c;发现它同时出现在…

云笔记小程序的实现

1.前言 云笔记, 是基于HotApp小程序统计云后台提供的api接口开发的一个微信小程序。 2.功能 离线保存笔记 云端数据同步, 更换了设备也可以找到以前的笔记 接入了好推二维码提供的数据统计工具, 可以到平台上查看用户分析、留存分析、事件分析。 3.界面效果 ***HotApp云笔…

Redis Pipelining 底层原理分析及实践

作者&#xff1a;vivo 互联网服务器团队-Wang Fei Redis是一种基于客户端-服务端模型以及请求/响应的TCP服务。在遇到批处理命令执行时&#xff0c;Redis提供了Pipelining(管道)来提升批处理性能。本文结合实践分析了Spring Boot框架下Redis的Lettuce客户端和Redisson客户端对…

行云堡垒国密算法应用与信创支持

一、 国密算法和信创的介绍 1.1 什么是国密算法 国密算法是国家密码管理局制定颁布的一系列的密码标准&#xff0c;即已经被国家密码局认定的国产密码算法&#xff0c;又称商用密码&#xff08;是指能够实现商用密码算法的加密&#xff0c;解密和认证等功能的技术&#xff09;…

excel里如何的科学计数法的数字转换成数值?

比如下图&#xff0c;要想把它们转换成3250跟1780&#xff0c;有什么快捷的办法吗&#xff1f; 科学计数法在excel里的格式&#xff0c;与我们常规在数学上写的有差异。这个转换可以这样做&#xff1a; 1.转换后的效果&#xff1a; 2.问题分析 题目中所附截图&#xff0c;单元…

Day96:云上攻防-云原生篇Docker安全系统内核版本漏洞CDK自动利用容器逃逸

目录 云原生-Docker安全-容器逃逸&系统内核漏洞 云原生-Docker安全-容器逃逸&docker版本漏洞 CVE-2019-5736 runC容器逃逸(需要管理员配合触发) CVE-2020-15257 containerd逃逸(启动容器时有前提参数) 云原生-Docker安全-容器逃逸&CDK自动化 知识点&#xff1…

Redis入门到通关之Set命令

文章目录 ⛄ 概述⛄ Set类型的常见命令⛄RedisTemplate API❄️❄️ 添加Set缓存(值可以是一个&#xff0c;也可是多个)❄️❄️设置过期时间(单独设置)❄️❄️根据key获取Set中的所有值❄️❄️根据value从一个set中查询,是否存在❄️❄️获取Set缓存的长度❄️❄️移除指定的…

云服务器安装Mysql、MariaDB、Redis、tomcat

前置工作 进入根目录 cd / 进入/user/local文件夹 上传压缩包 rz 压缩包 Mysql 1.下载并安装MySQL官方的 Yum Repository wget http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm rpm -ivh mysql-community-release-el7-5.noarch.rpm yum install mysql-…

博途v17与winCC安装流程与踩坑记录

博途v17与winCC7.5安装教程与踩坑记录 安装教程博途安装流程第一步 注册表删除第二步 启用.NET Framework服务第三步 正式安装 winCC安装流程 博途v17与winCC安装记录win11家庭版 安装教程 首先说明&#xff0c;本文安装针对的是TIA portal V17 (64bit)与winCC 7.5SP2。安装在…

基于ollama搭建本地chatGPT

ollama帮助我们可以快速在本地运行一个大模型&#xff0c;再整合一个可视化页面就能构建一个chatGPT&#xff0c;可视化页面我选择了chat-ollama&#xff08;因为它还能支持知识库&#xff0c;可玩性更高&#xff09;&#xff0c;如果只是为了聊天更推荐chatbox 部署步骤 下载…

科研学习|科研软件——如何使用SmartPLS软件进行结构方程建模

SmartPLS是一种用于结构方程建模&#xff08;SEM&#xff09;的软件&#xff0c;它可以用于定量研究&#xff0c;尤其是在商业和社会科学领域中&#xff0c;如市场研究、管理研究、心理学研究等。 一、准备数据 在使用SmartPLS之前&#xff0c;您需要准备一个符合要求的数据集。…

1.MMD模型动作场景镜头的导入及视频导出

界面介绍 MIKUMIKUDANCE926版本 MMD的工具栏模型骨骼帧的窗口&#xff0c;在不同时间做不同动作&#xff0c;可以在这里打帧操作时间曲线操作窗口&#xff0c;控制模型两个动作之间的过渡模型操作窗口&#xff0c;导入模型选择模型相机操作&#xff0c;控制相机远近&#xf…