四种引用类型在Springboot中的使用

简介: 文章概览一.  四种引用的概念二.  对象可达性介绍三.  Springboot源码中的引用概念介绍不同的引用类型,主要体现的是对象不同的可达性(reachable)状态和对垃圾收集的影响。01.  强引用这个就是我们创建的普通对象了~ 当该对象被显示地赋值为 null 时,或者没有被其他存活的对象继续引用时,它就会成为垃圾收集器的目标,等待被收回02.  软引用软引用( SoftReference ) , 当内存不足 时会被回收比如被回收后,这里会打印 null 而不是 Java4ye03.  弱引用弱引用( WeakReference ) , 当 垃圾回收

文章概览


一.  四种引用的概念


二.  对象可达性介绍


三.  Springboot源码中的引用


概念介绍


不同的引用类型,主要体现的是对象不同的可达性(reachable)状态和对垃圾收集的影响


01.  强引用


这个就是我们创建的普通对象了~  当该对象被显示地赋值为 null 时,或者没有被其他存活的对象继续引用时,它就会成为垃圾收集器的目标,等待被收回


02.  软引用


软引用( SoftReference ) , 当内存不足 时会被回收


比如


网络异常,图片无法展示
|


被回收后,这里会打印 null 而不是 Java4ye


03.  弱引用


弱引用( WeakReference ) , 当 垃圾回收器 进行垃圾回收时,无论内存足与否,它都会被垃圾回收器回收


比如


网络异常,图片无法展示
|


被回收后,这里也是会打印 null 而不是 Java4ye


04.  虚引用


虚引用( ReferenceQueue ) , 这个也是随时会被回收,不过它的作用更像一个标记,当对象被回收时,它不为 null ,但是要注意,无论什么时候去调用 虚引用的 get 方法,都只能获取到一个 null 值。


为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知 —— <<深入理解Java虚拟机>>


这里引用 www.javashuo.com/article/p-z… 该文章的例子


User user = new User(1, "Java4ye");
ReferenceQueue<User> userReferenceQueue = new ReferenceQueue<>();
// 创建User对象的虚引用
PhantomReference<User> phantomReference = new PhantomReference<>(user, userReferenceQueue);
// 去掉强引用
user = null;
System.out.println(phantomReference.get());
// 手动触发GC
System.gc();
System.out.println("GC: " + phantomReference.get());
Reference<? extends User> reference = null;
try {
    reference = userReferenceQueue.remove(1000);
} catch (InterruptedException e) {
    e.printStackTrace();
}
if (reference != null) {
    System.out.println("对象User被回收了:");
}
复制代码


对象可达性


那么 简单介绍完上面的 4 种引用后,我们再来看看它的可达性~


如图~


网络异常,图片无法展示
|


  1. 强可达: 比如 创建一个对象时,创建它的线程对该对象就是强可达


  1. 软可达: 只能通过软引用访问


  1. 弱可达: 只能通过弱引用访问


  1. 虚可达: 当对象没有 强,软,弱 引用关联时,并且 finalize 过,就会进入该状态


  1. 不可达: 意味着该对象可以被清除了。


通过最开始的代码例子和上面的图(双向箭头)我们还可以发现,软引用和弱引用和强引用这三者间可以进行转换( 通过 Referenceget() 可获取到原对象),这意味着:


对于软引用、弱引用之类,垃圾收集器可能会存在二次确认的问题,以保证处于弱引用状态的对象,没有改变为强引用。


JDK8 中,还可以通过 指定参数打印引用的相关信息


-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintReferenceGC

JDK8 中使用 ParrallelGC 收集的垃圾回收日志 (大佬 pdf 中的例子)


0.403: [GC (Allocation Failure) 0.871: [SoftReference, 0 refs, 0.0000393 secs]0.871: [WeakReference, 8 refs, 0.0000138 secs]0.871: [FinalReference, 4 refs, 0.0000094 secs]0.871:

[PhantomReference, 0 refs, 0 refs, 0.0000085 secs]0.871: [JNI Weak Reference, 0.0000071 secs][PSYoungGen: 76272K->10720K(141824K)] 128286K->128422K(316928K), 0.4683919 secs] [Times:

user=1.17 sys=0.03, real=0.47 secs]


再记录下这个点👇(哈哈 不知道啥时候才会用上~)


通过底层API来达到强引用👍


网络异常,图片无法展示
|


Springboot源码中的使用


嘿嘿  终于来到重点了 ,正如开头提到的~  4ye 也是在 Springboot 源码中看到这个

ConcurrentReferenceHashMap 才想起要写一下这篇文章滴✍


那么这个 ConcurrentReferenceHashMap  到底有什么作用呢?


ConcurrentReferenceHashMap能指定所存放对象的引用级别


默认情况下是 软引用级别


网络异常,图片无法展示
|


比如 在 Springboot自动装配原理探索 一文中提到的 Springboot SPI 机制 其中的主角: SpringFactoriesLoader


源码如下:


网络异常,图片无法展示
|


还有自动配置过程中的注解扫描AnnotationsScanner


网络异常,图片无法展示
|


以及在 万字长文,带你快速上手这些池化技术! 一文中出现的 异步任务线程池


ThreadPoolTaskExecutor


源码如下: (可以看到这里指明了是 弱引用级别


网络异常,图片无法展示
|


总结


  1. 看完上面的例子,觉得可以模仿下 SpringbootConcurrentReferenceHashMap  ,对对象进行一个合理的存储,间接地优化jvm ,提高垃圾回收的效率。


  1. 这两个别搞混了: 软引用,内存不足时回收弱引用,在进行垃圾回收时,不管内存足与否,都会被回收,



目录
相关文章
|
5月前
|
存储 人工智能 自然语言处理
AI在法律行业难以从简单工具转变为认知引擎,法律知识图谱如何解决这一难题?
本文AI产品专家三桥君探讨了AI如何从法律行业的辅助工具升级为具备认知能力的智能引擎。通过构建法律知识图谱,AI可实现法条精准引用、案件智能分析等核心功能,解决法律语义鸿沟和动态更新等挑战。三桥君介绍了知识图谱的构建过程及其在案件匹配、法条推理中的应用场景,并展示了智能助理在录音转写、案例检索、文书生成等实务中的落地价值。三桥君认为,法律知识图谱将推动AI从工具属性向认知引擎跃迁,提升法律服务效率与透明度。
268 1
|
Arthas 监控 Java
Arthas 实践——生产环境排查 CPU 飚高问题
13:40 收到我们的生产环境服务器绿版 CUP 超负载告警通知。此时心里只有一个想法,重启大法好,马上登录服务器,执行 top 发现进程 30247 和 28337 占用 CPU 为 200 多和100 多基本占用了 4 核的 3 核,整个过程大概用时 30 秒,维护群依然很平静,运营的电话也没打过来,这时候我断定,这次问题应该影响面很小,用户可能也暂时没有发现,好吧,还有时间做排查。
Arthas 实践——生产环境排查 CPU 飚高问题
|
开发者 程序员
基于阿里云快速搭建数字营销引擎【计算广告】
阿里云营销引擎有别于其他阿里云产品,它是配合阿里云MaxComputer,画像分析,分析型数据库等多个云产品,并在高德DMP和友盟+DMP提供人群分析能力的基础上,提供一整套数字营销解决方案。 在过去搭建一套成熟DSP平台需要一个强大的技术和业务团队,现在只需要一个人就能够轻松完成,大幅降低了系统构建的基础设施成本,运维成本,容灾成本,开发成本,时间成本。
3530 0
|
关系型数据库 MySQL 数据库
一个 MySQL 数据库死锁的案例和解决方案
本文介绍了一个 MySQL 数据库死锁的案例和解决方案。
801 3
|
监控 jenkins 持续交付
Docker和Jenkins有什么不同
【10月更文挑战第18天】Docker和Jenkins有什么不同
|
存储 关系型数据库 MySQL
MySQL数据库锁:共享锁和独占锁
本文详细介绍了`InnoDB`存储引擎中的两种行级别锁:共享锁(S锁)与排他锁(X锁)。通过具体示例展示了这两种锁的工作机制及其在`InnoDB`与`MyISAM`引擎中的表现差异。文章还提供了锁的兼容性矩阵,帮助读者更好地理解锁之间的互斥关系。最后总结了两种锁的特点及适用场景。适合希望深入了解`MySQL`并发控制机制的读者阅读。
488 1
|
网络协议 程序员 数据库
什么是公网IP和内网IP
【10月更文挑战第27天】公网IP与内网IP是网络通信中的两个重要概念。公网IP是互联网上的唯一标识,而内网IP仅在局域网内部有效,用于局域网内的设备通信。由于IPv4地址资源有限,通常一个公司或家庭只有一个公网IP,内部设备通过NAT(网络地址转换)技术共享该公网IP访问互联网。这样不仅节省了IP资源,还提高了网络安全性和稳定性。
1156 0
|
前端开发 JavaScript 程序员
后端程序员的前端捷径-超级容易上手使用的前端框架layUI(下)
后端程序员的前端捷径-超级容易上手使用的前端框架layUI
242 9
|
自然语言处理 JavaScript 前端开发
JDK序列化原理问题之FuryJDK序列化性能问题的如何解决
JDK序列化原理问题之FuryJDK序列化性能问题的如何解决
245 2
|
消息中间件 监控 Java
惊呆了!Python性能测试高手都用这些神器:JMeter+Locust,效率翻倍📈
【8月更文挑战第4天】在软件开发中,性能测试至关重要。JMeter与Locust分别是跨平台与Python专用的性能测试利器。JMeter功能强大,支持多种协议,图形界面友好;而Locust则利用Python的协程实现高并发,代码清晰易维护。两者均可扩展,支持分布式测试。结合使用时,JMeter测试非Web服务,Locust专注Python Web服务,互补优势,大幅提升测试效率和准确性,为应用稳定运行提供坚实保障。
319 0