当前位置: 首页 > news >正文

一文弄清Java的四大引用及其两大传递

开场白

Hello大家好呀,我是CodeCodeBond
最近在复习很多很多的基础知识,有了很多新的感悟~


在这里插入图片描述
话不多说,直接发车✈


四大引用

问题切入点

在学习 Thread线程利用ThreadLocalMap实现线程的本地内存(变量副本)的时候,是基于ThreadLocal为Key,Object为Value的一个Entry。并且,这个Entry键值对的键是使用了一个弱引用,且说道这样会存在一个内存泄漏的问题。
在这里插入图片描述
那么为什么会内存泄露呢?这个弱引用是什么呢?又有哪些引用呢?他们之间有什么区别呢?

怀揣着一堆问题,我开始了学习— 🐻

其实引用类型的选择也是垃圾回收、是否可达的策略选择!

所以我们从垃圾回收和可达性这两个方面去理解Java的四种引用类型!

Java有哪四种类型的引用?

可达性分析是JVM中垃圾回收的垃圾判断算法,通过从GC Root出发->遍历引用链判断对象是否可达判断对象是否进行垃圾回收,具体GC Root是什么,垃圾回收算法是什么就不多赘述了。

强引用

定义: 强引用是最常用最常见的引用,我们正常使用没有特别处理的都是强引用的场景。

特点

  • 只要有一个对象是强引用指向它,就不会被垃圾回收。
  • 在可达性分析中,从GC Roots开始的引用链上,只要有强引用链条存在,目标对象就被视为可达。

软引用

定义: 软引用通过SoftReference类来实现,允许垃圾回收器在内存不足时回收这些对象。

特点

  • 软引用对象在内存充足时不会被回收,但在内存不足时可能会被回收。
  • 在可达性分析中,软引用对象不被立即视为可达,只有在内存充足的情况下,软引用对象才被保留。

弱引用

定义:弱引用通过WeakReference类来实现,允许垃圾回收器在下一次垃圾回收时回收这些对象。

影响

  • 弱引用对象在下一次GC时大概率会被回收,不论内存是否充足。
  • 在可达性分析中,弱引用对象不会被视为可达,即使对象有弱引用,仍然会被回收。

虚引用

定义:虚引用通过PhantomReference类来实现,主要用于跟踪对象的回收状态。(像一次性用品)

影响

  • 虚引用对象本身并不会影响对象的生命周期,它们总是在GC时被回收。
  • 在可达性分析中,虚引用对象从未被视为可达。它们主要用于管理系统资源的回收和清理。

回归问题

回到问题的开始,为什么ThreadLocalMap会存在内存泄漏的问题呢?主要原因就是因为身为Key的ThreadLocal是一个弱引用的存在,它在没有外部强引用的前提下,很可能被直接垃圾回收掉,但是Value是一个Object的强引用,导致Key被gc了,但是Value还在。也就是我们说的内存泄露的问题了。

ThreadLocalMap 实现中已经考虑了这种情况,在调用 set()get()remove() 方法的时候,会清理掉 key 为 null 的记录。使用完 ThreadLocal方法后最好手动调用remove()方法,预防一下。

两大传递

两大传递一般指的是值传递引用传递

但是,在Java中是不存在引用传递的,Java所有的传递都是值传递

我们一起来简单证明一下:

基本数据类型

引用数据类型 试验1

public class Test {public static void main(String[] args) {String s1 = "CodeCodeBond";modifyString(s1);System.out.println(s1);}public static void modifyString(String s){s = "GGBond!";}
}
//打印结果不变
//CodeCodeBond

这是一个最简单的String引用类型,可以看到修改后打印结果不变,这个例子可以说明String是值传递的,方法的形参并没有影响原来的实参。

引用数据类型 试验2

注意看!!

public class Test {public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("1");list.add("2");list.add("3");System.out.println("init:" + list);modify(list);System.out.println("modify later:" + list);}public static void modify(ArrayList<String> list){list.add("CodeCodeBond");}
}

在这里插入图片描述
我们可以看到实参集合居然被修改了,不是说是值传递吗?为什么实参被修改了?

原来,Java对于对象引用类型,传递的是引用的副本(内存地址值)。通过这个引用副本可以修改原始对象的内容。

思考题 Question

但是我们看回试验1的String引用类型为什么不能修改实参呢?

可以思考一下这个问题~文末Answer我们再来解答这个问题(点击目录快速跳转)

引用数据类型 试验3

为了进一步证明Java中确实只有值传递,我们来进行试验3

public class Test {public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("CodeCodeBond");System.out.println("init:" + list);modify(list);System.out.println("modify later:" + list);}public static void modify(ArrayList<String> list){list = new ArrayList<>();list.add("GGBond");}
}

打印结果如图:
在这里插入图片描述
看吧,在方法中我们重新将引用副本指向一个新的地址,但是实参并没有被改变,也就强力的说明了传递的是一个引用副本,有力证明了Java中确实只存在值传递这一说!


最后的最后

思考题 Answer

为什么试验1中,String类值传递引用副本值的时候,无法修改原来实参呢?因为在方法中修改的时候是通过直接赋值的操作来修改,而String是一个final class不可变类,所以String机制是新建一个String对象去存储"CodeCodeBond"字符串的,所以并不能修改实参,你想到了吗?😄

我是CodeCodeBond,我的座右铭是

比上次好,比下次差。

我们下次见! 8.3 1:25
在这里插入图片描述

相关文章:

一文弄清Java的四大引用及其两大传递

开场白 Hello大家好呀&#xff0c;我是CodeCodeBond✊最近在复习很多很多的基础知识&#xff0c;有了很多新的感悟~ 话不多说&#xff0c;直接发车✈ 四大引用 问题切入点 在学习 Thread线程利用ThreadLocalMap实现线程的本地内存&#xff08;变量副本&#xff09;的时候&…...

arduino程序-MC猜数字5、6(基础知识)

arduino程序-MC猜数字5、6&#xff08;基础知识&#xff09; 1-23 MC猜数字-5 自定义函数自定义函数自定义清理显示内容函数displayClear&#xff08;&#xff09;带参数函数displayNumber带参数、返回值的函数 1-24 MC猜数字-6 完成制作显示0~9数字函数改造产生随机数字函数改…...

【笔记】如何在ps里调整贴图

如图我想要在ps里把角上半部分画成绿色 1.打开ps&#xff0c;拖进贴图 2.把所有图层全选复制&#xff0c;除了实体、选择、背景和uv图层 3.把这些图层合并 4.自己手动选上半部分角 按shift加选 alt减选 5. 这里可以调整饱和度、色相、明度 6. 选好之后用羽化之后边缘会…...

【C++11】深度解析--异步操作(什么是异步?异步有那些操作?异步操作有什么用呢?)

目录 一、前言 二、什么是异步操作呢&#xff1f; &#x1f525;异步的概念&#x1f525; &#x1f525;异步的生活案例说明&#x1f525; 三、异步有那些操作呢&#xff1f; &#x1f525;std::future&#x1f525; &#x1f4a2;std::future 的概念&#x1f4a2; &a…...

PHP苹果 V X iPhone微商i o s多分开V X语音转发密友朋友圈一键跟圈软件

苹果VX神器&#xff01;iPhone微商必备&#xff1a;ios多开、VX语音转发、密友朋友圈一键跟圈软件大揭秘&#xff01; 一、iOS多开新境界&#xff0c;工作生活两不误&#xff01; 你是不是也烦恼过&#xff0c;想要在工作号和生活号之间自由切换&#xff0c;却因为iPhone的限制…...

LDR6020 iPad皮套一体式键盘充电方案解析

在移动办公与学习的浪潮中&#xff0c;iPad凭借其强大的性能与便携性&#xff0c;成为了越来越多人的首选设备。然而&#xff0c;随着工作与学习任务的日益复杂&#xff0c;单一的触控操作已难以满足高效、精准的需求。因此&#xff0c;搭配一款优秀的键盘成为了提升iPad使用体…...

一款功能强大且免费的跨平台图片批量处理工具

XnConvert是一款功能强大且免费的跨平台图片批量处理工具&#xff0c;广泛应用于个人用户、教育机构和非营利组织。它支持超过500种图片格式&#xff0c;包括常见的JPEG、PNG、TIFF、GIF、WebP、PSD、JPEG2000等&#xff0c;并能够导出为大约70种不同的文件格式。 该软件的主要…...

用Python打造精彩动画与视频,4.2 特效和滤镜的使用

第四章&#xff1a;深入MoviePy 4.2 特效和滤镜的使用 在视频制作和编辑过程中&#xff0c;特效和滤镜是不可或缺的元素。它们不仅能增强视觉效果&#xff0c;还能赋予视频独特的风格和情感。MoviePy 作为一个功能强大的视频编辑库&#xff0c;提供了多种内置的特效和滤镜&…...

在 iOS 系统中,如何设置才能更好地保护个人隐私?

在iOS系统中&#xff0c;有一些设置和功能可以帮助您更好地保护个人隐私。以下是一些建议&#xff1a; 使用设备锁&#xff1a;设置一个强密码、Touch ID或Face ID来锁定您的设备。这可以防止其他人访问您的设备和个人信息。 更新软件&#xff1a;及时更新您的iOS系统和应用程…...

Charles抓包工具系列文章(七)-- Rewrite工具的应用示例

一、背景 客户端通过域名访问后端服务,在api网关层,会判断path的前缀,默认/api开头的请求都转发至后端服务A。 当前缀是/assist/api开头,请求将转发至后端服务B(部署在192.168.80.226,便于测试对比) 在不改动kong网关配置的情况下,现需要把后者的请求转发至192.168.…...

国内SSL证书颁发机构哪家服务更优质?

SSL证书作为保障网站数据传输安全的关键工具&#xff0c;其重要性不言而喻。选择一个可靠的SSL证书代理商&#xff0c;不仅能够提供多样化的证书类型&#xff0c;而且能在众多品牌中进行比较&#xff0c;选择最适合自己的、性价比更高的产品。此外&#xff0c;优质的代理商还能…...

鸿蒙系统开发【设备安全服务-应用设备状态检测】安全

设备安全服务-应用设备状态检测 介绍 本示例向您介绍如何在应用中获取DeviceToken用于对应用的设备状态进行检测。 需要使用设备安全服务接口 kit.DeviceSecurityKit。 效果预览 Sample工程的配置与使用 在DevEco中配置Sample工程的步骤如下 [创建项目]及[应用]。打开Sam…...

19个运维工程师面试集锦

第一部分&#xff1a;Linux基础 题目1&#xff1a; 有一百个图片文件&#xff0c;它们的地址都是 http://down.xiaomi.com/img/1.png http://down.xiaomi.com/img/2.png … 一直到 http://down.xiaomi.com/img/100.png 如何批量下载这100个图片文件&#xff0c;并找出其中大…...

一芯解锁「看家」新体验,航芯高性价比猫眼智能锁方案,让安全看得见!

随着智能门锁市场规模逐年递增&#xff0c;行业“内卷”也持续激烈。伴随着一路加码的功能卖点&#xff0c;智能门锁制造商正面临着产品功能芯片增多和成本优化的双重挑战。消费者不仅追求易用性、智能化和美观性&#xff0c;更期待产品具有良好的性价比。 而在智能门锁的众多…...

IPv4 vs IPv6:了解这两大协议的关键差异

我发现&#xff0c;很多找代理IP的朋友在后台问我的问题都很相似&#xff01;都被配置IP的最后一步&#xff1a;选择IPv4还是IPv6&#xff1f;给难住了。昨晚我一晚没睡&#xff0c;终于整理出对IPv4和IPv6的对比总结&#xff0c;从概念阐述到特点对比&#xff0c;再解答IPv6总…...

C#知识|XML文件操作

哈喽,你好啊,我是雷工! 之前有朋友在群里聊XML文件操作的问题,今天正好学习相关内容, 以下为学习笔记。 01 XML介绍 ①:XML是eXtensible Markup Language的缩写,即扩展标记语言。 ②:XML是一种可以用来创建自定义的标记语言,由W3C(万维网协会)创建,用来克服HTML的局…...

TCP 和 UDP 之间的区别?

从 连接&#xff0c;可靠性&#xff0c;传输方式等方面&#xff1a; TCP 是面向连接的协议&#xff0c;在发送数据的时候需要先通过 TCP 的三次握手&#xff0c;而 UDP 是无连接的协议&#xff0c;可以直接传输数据TCP 通过超时重传&#xff0c;流量控制和拥塞控制等方法保障了…...

共用体、枚举类型、typedef定义,位运算

共用体 union 共用体名 { 数据类型1 成员变量1; 数据类型2 成员变量2; 数据类型3 成员变量3; ... }; 共用体所有成员变量&#xff0c;所占空间重叠&#xff0c;占共同的空间。 枚举 将变量的值一一列举出来。 enum 枚举类型名…...

【运维】Linux如何批量解压文件夹下的很多个`.tar.gz`文件

要在Linux中批量解压这些.tar.gz文件&#xff0c;你可以使用tar命令配合find或者bash的通配符功能。这里是一个简单的步骤来解压所有这些.tar.gz文件&#xff1a; 方法 1: 使用 find 命令 find . -type f -name "*.tar.gz" -exec tar -xzvf {} \;这个命令的意思是从…...

centos9安装jumpserver并导入域用户

jumpserver是使用最广泛的开源堡垒机&#xff0c;依赖 mysql/mariadb、postgresql、redis 3个数据库。 当前版本为 4.0.1&#xff0c;安装包&#xff1a; jumpserver-ce-v4.0.1-x86_64.tar.gz 0、安装centos9&#xff0c;安装docker 1、解压安装包 cd /opt tar -xf jumpser…...

零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?

一、核心优势&#xff1a;专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发&#xff0c;是一款收费低廉但功能全面的Windows NAS工具&#xff0c;主打“无学习成本部署” 。与其他NAS软件相比&#xff0c;其优势在于&#xff1a; 无需硬件改造&#xff1a;将任意W…...

7.4.分块查找

一.分块查找的算法思想&#xff1a; 1.实例&#xff1a; 以上述图片的顺序表为例&#xff0c; 该顺序表的数据元素从整体来看是乱序的&#xff0c;但如果把这些数据元素分成一块一块的小区间&#xff0c; 第一个区间[0,1]索引上的数据元素都是小于等于10的&#xff0c; 第二…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互

引擎版本&#xff1a; 3.8.1 语言&#xff1a; JavaScript/TypeScript、C、Java 环境&#xff1a;Window 参考&#xff1a;Java原生反射机制 您好&#xff0c;我是鹤九日&#xff01; 回顾 在上篇文章中&#xff1a;CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

CMake 从 GitHub 下载第三方库并使用

有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj&#xff0c;再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

Typeerror: cannot read properties of undefined (reading ‘XXX‘)

最近需要在离线机器上运行软件&#xff0c;所以得把软件用docker打包起来&#xff0c;大部分功能都没问题&#xff0c;出了一个奇怪的事情。同样的代码&#xff0c;在本机上用vscode可以运行起来&#xff0c;但是打包之后在docker里出现了问题。使用的是dialog组件&#xff0c;…...

安卓基础(aar)

重新设置java21的环境&#xff0c;临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的&#xff1a; MyApp/ ├── app/ …...

【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)

LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 题目描述解题思路Java代码 题目描述 题目链接&#xff1a;LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...

提升移动端网页调试效率:WebDebugX 与常见工具组合实践

在日常移动端开发中&#xff0c;网页调试始终是一个高频但又极具挑战的环节。尤其在面对 iOS 与 Android 的混合技术栈、各种设备差异化行为时&#xff0c;开发者迫切需要一套高效、可靠且跨平台的调试方案。过去&#xff0c;我们或多或少使用过 Chrome DevTools、Remote Debug…...

vue3 daterange正则踩坑

<el-form-item label"空置时间" prop"vacantTime"> <el-date-picker v-model"form.vacantTime" type"daterange" start-placeholder"开始日期" end-placeholder"结束日期" clearable :editable"fal…...