Spring 只用一招,就摆脱被垃圾回收的命运,拯救了自己

SpringBoot ApplicationContext 会被 JVM 当成垃圾对象,然后回收掉吗?

最近五阳哥在复习JVM 垃圾回收的知识,被别人问到这个问题,我心里感到一惊,如果Spring 被回收掉,Spring管理的bean全部会被回收,那我们的Java应用不就被一锅端了吗? 这太可怕了……

虽然我相信 Spring一定会处理好这个问题,确保自身不被垃圾回收,但是巨大的好奇心,驱使我一探究竟。

我们在岁月静好时,Spring帮我们做了哪些事情?

回顾一下,垃圾回收的基础知识

精通Java GC的可以跳过这一段。

五阳哥,前两天写了一篇文章,分析为什么gc一定需要Stop the world? # 点击查看,这篇文章? ,里面已经总结道,“当一个对象无法被 GC Root引用到,那么这个对象将在接下来的垃圾回收过程中被回收”。

在Java堆中,存放着所有Java的对象实例。在进行垃圾收集之前,JVM需要确定哪些对象已经不被使用(即垃圾),哪些对象仍然被使用。为了判断对象是否是“垃圾”,JVM采用了可达性分析算法。

可达性分析算法 是指通过指定 GC Root 根对象,从根对象开始搜索引用的对象,通过引用链条,层层遍历链条上的对象,可以到达的对象不可被垃圾回收。而最终没有被搜索遍历到的对象,则为 不可达对象,应该被垃圾回收。

JVM中的 GC Root根对象包括如下:

  1. 虚拟机栈引用的对象
  2. 本地方法栈内JNI(本地方法)引用的对象
  3. 方法区中类静态属性引用的对象
  4. 方法区中常量引用的对象
  5. Java虚拟机内部的引用

如果 Spring 想不被垃圾回收,那么Spring一定要确保自己被以上 GC Root引用,以上五个,任意一个即可。

接下来,我们将分析Spring 源码!找到Spring不被垃圾回收的奥秘!

启动Spring Boot应用

以下代码启动了一个Spring Boot应用,这是官方推荐的启动方式,通过注解的方式,把启动类传递给 SpringApplication ,调用run 方法,启动Spring Boot。

614c38849578dd569a87136361a46739.jpeg

需要说明的是,run方法在Spring boot启动成功后,会立即返回,不会被阻塞。所以 main 线程在启动Spring boot后,将退出……

由于Spring Boot会启动Jetty/Tomcat等其他线程池,所以Java应用并不会退出。因为Java进程退出条件之一是:所有非守护线程全部退出,则JVM退出 点击查看 JVM 如何退出的详细信息 ,所以只有 main 线程退出,其他业务线程还存在情况下,Java不会退出。

由此可见,main 线程在启动 Spring Boot后,并不会一直持有 Spring boot 对象引用,官方文档里也没有 强调,一定要保持 main 线程 不退出。Spring Boot需要把自己交到其他对象手中,确保自己不被回收!

那么如何保证 Spring Boot不被垃圾回收呢?我需要从 SpringApplcaition 内部找原因!

Spring Boot 和 Tomcat

从上面的代码可以看到 Spring Boot控制了Java应用的入口,而Web容器 Tomcat等被Spring 管理,如果Spring不会被垃圾回收,那么Tomcat就不用担心被垃圾回收。

而在Spring Boot之前的Web应用,都是将Java项目打包到Tomcat容器中执行。那时候 Spring MVC和Spring 是要被Tomcat容器管理的,所以那时的Spring项目不用担心 被垃圾回收的问题。

而现在 Tomcat和 Spring boot的角色互换,决定了 Spring Boot应用必须要处理好垃圾回收问题!

探究Spring Boot代码

创建和启动上下文

下图是 SpringApplication.run方法的源代码,run 方法主要执行两步,创建 Spring 上下文和启动上下文。 91d550c1a26f19b841a1543cb3209548.jpeg

刷新上下文的奥秘

在Spring Boot刷新上下文的代码中,首先调用 Spring Application.refresh方法启动Spring 上下文。然后 Spring boot就把 Close 方法注册到 Java shutdownHook 关闭钩子程序中!

d3eccb830c26f73fb5be16be0c68a081.jpeg基本上可以破案了!

因为Spring Boot控制了Java程序的入口,所以要负责整个项目的关闭流程,于是它 注册了Java关闭钩子。

76f4004b3d07d79cdfbb972761261dfa.jpeg

接下来,我们看一下注册关闭钩子,会被 GC Root引用到吗?

关闭钩子

add 方法,将钩子程序注册到 一个容器中!

0e6d56f752344e6ea59857690c1f1fda.jpeg

可以看到 Thread 类型的 钩子程序,被保存在 hooks Map 中。

而hooks列表的类型定义是 static 类型的。 static 变量都是GC Root。

2a72e97a37e725a1b268d3e7aff48d82.jpeg

总结

Spring Boot 在启动时会将关闭流程注册到 Java 关闭钩子中,并通过关闭钩子线程引用到 Spring 上下文。

关闭钩子会被保存在一个 static 静态类型的 Map 中,这个 Map 在 GC Root 上。

因此,Spring Boot 不被垃圾回收的关键是在启动时注册了关闭钩子。

破案了,spring永远不会被垃圾回收。

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

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

相关文章

【Proteus仿真】【Arduino单片机】HC-SR04超声波测距

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真Arduino单片机控制器,使用PCF8574、LCD1602液晶、HC-SR04超声波传感器等。 主要功能: 系统运行后,LCD1602显示超声波检测距离。 二、软件设计 …

vcenter server (部署较大服务器)

作用 VMware vCenter是集中管理控制台,管理所有安装了VMware ESXI的主机 使用vCenter Server可以对虚拟机进行实时的监控,包括服务器硬件、网络和共享的存储,并可以进行故障诊断。 可以查看实时的统计和图表,监控虚拟主机和资源…

盘点49个Python网站项目Python爱好者不容错过

盘点49个Python网站项目Python爱好者不容错过 学习知识费力气,收集整理更不易。 知识付费甚欢喜,为咱码农谋福利。 链接:https://pan.baidu.com/s/1aFYJtNZjgst1l5KFBckP2A?pwd8888 提取码:8888 项目名称 A simpleshorturl…

使用vscode的ssh进行远程主机连接

1. 首先安装好“远程资源管理器”(这一步建议谷歌下),如下图所示 2. 按F1,设置远程主机信息的SSH Configuration config file, 注意这里可以添加多个远程主机信息,通过注释掉无关远程主机信息来选择想连接的那个主机&a…

国产双核DSP与 TI 的TMS320F28377 大PK

国产DSP,QX320F28377与 TI的 TMS320F28377 孰强孰弱

计算机毕业设计项目选题推荐(免费领源码)PHP+MySQL在线网络教育平台66984

目 录 摘要 1 绪论 1.1 课题背景 1.2意义 1.3HTML介绍 1.4JavaScript 运行模式 1.5css3工作原理 1.6论文结构与章节安排 2 在线网络教育平台分析 2.1 可行性分析 2.2 系统流程分析 2.2.1数据增加流程 3 2.2.2数据修改流程 4 2.2.3数据删除流程 4 2.3 系统功能分析 …

新生儿吐奶:原因、科普和注意事项

引言: 新生儿吐奶是许多新父母常见的经历,尽管大多数情况下是正常的,但对于父母来说,了解吐奶的原因以及如何处理是至关重要的。本文将科普新生儿吐奶的原因,提供相关信息,并为父母和监护人提供注意事项&a…

第二篇 《随机点名答题系统》——题库管理详解(类抽奖系统、在线答题系统、线上答题系统、在线点名系统、线上点名系统、在线考试系统、线上考试系统)

目录 1.功能需求 2.数据库设计 3.流程设计 4.关键代码 4.1.题库维护 4.1.1数据请求示意图 4.1.2添加题库(login.php)数据请求代码 4.1.3删除题库(login.php)数据请求代码 4.1.4 业务处理Service(tiKuService…

Redis最新2023年面试题高级面试题及附答案解析(1)【Redis最新2023年面试题高级面试题及附答案解析-第三十八刊】

文章目录 Redis最新2023年面试题高级面试题及附答案解析(1)01、为什么 Redis 需要把所有数据放到内存中?02、查看 Redis 使用情况及状态信息用什么命令?03、MySQL里有2000w数据,Redis 中只存20w的数据,如何保证 Redis 中的数据都是…

Spring Boot MyBatis Plus 配置数据源详解

文章目录 1. 引入 MyBatis Plus 依赖2. 数据源配置3. MyBatis Plus 配置4. 动态数据源配置(多数据源)5. 小结 🎉欢迎来到架构设计专栏~Spring Boot MyBatis Plus 配置数据源详解 ☆* o(≧▽≦)o *☆嗨~我是IT陈寒🍹✨博客主页&…

Linux电脑投屏到电视的简洁操作

Linux电脑投屏到安卓电视有多种好处。 首先,通过将Linux电脑与安卓电视连接,用户可以轻松地将电脑屏传输到电视上,从而获得更加舒适和清晰的视觉体验。 其次,投屏功能可以帮助用户在电视上展示电脑中的图片、视频和其他多媒体文件…

GitHub Universe 2023:AI 技术引领软件开发创新浪潮

GitHub 是全球领先的软件开发和协作平台,数百万开发者和企业在此分享、学习和创建卓越的软件。同时 GitHub 处在 AI 技术前沿,通过其先进的 AI 技术增强开发者体验并赋能未来软件开发的使命。在今天的文章中,我们将一起看看在 GitHub 年度大会…

InputStream和OutputStream

文章目录 💡FileInputStream 构造方法💡InputStream 常用方法💡OutputStream 概述💡OutputStream 常用方法💡PrintWriter💡小程序练习 使用字节流进行读/写操作时,是以字节为单位的;…

常用网络命令(实习报告)

南京信息工程大学 实验(实习)报告 实验(实习)名称 常用网络命令 实验(实习)日期 2017/5/25 得分 指导教师 *** 专业 网络工程 年级 2015 班次 1 姓名 *** …

java排序算法之桶排序

图解 桶排序(Bucket sort)是一个排序算法,它的主要思想是将需要排序的数据分到有限数量的桶里。每个桶里的数据再进行单独的排序,最后按照顺序将每个桶里的数据依次取出,即可完成排序。 桶排序的具体实现可以分为以下几…

【2021集创赛】 RISC-V杯三等奖:基于E203 处理器的SM4算法硬件加速

杯赛题目:基于蜂鸟E203 RISC-V处理器内核的SoC设计 参赛要求:研究生组/本科生组 赛题内容: 基于芯来科技的开源蜂鸟E203 Demo SoC进行扩展,在限定的可编程逻辑平台上构建面向专用应用领域(譬如人工智能、信息安全、工业…

动手学深度学习——语言模型和数据集(代码详解)

文章目录 语言模型与数据集1. 学习语言模型2. 马尔可夫模型与n元语法3. 自然语言统计4. 读取长序列数据4.1 随机采样4.2 顺序分区 语言模型与数据集 了解到如何将文本数据映射到词元,以及将这些词元视作一系列的离散观测,例如单词或字符。 给定一个文本…

《洛谷深入浅出进阶篇》P3397 地毯————二维差分

上链接:P3397 地毯 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P3397 上题干: 题目描述 在 nn 的格子上有 m 个地毯。 给出这些地毯的信息,问每个点被多少个地毯覆盖。 输入格式 第一行,两个…

配置sonarQube

1.新版本需要安装JDK11以上版本 2.修改解压(解压在一个路径不包含特殊符号、中文、空格的位置里)出来的sonar文件夹中conf下面的配置文件(sonar.properties) sonar.jdbc.usernameXXX sonar.jdbc.passwordXXXsonar.jdbc.urljdbc:sqlserver://172.168.1.…

小学生写作业用什么台灯好?专业的学生台灯推荐

说到台灯相信大家都不陌生,不管是办公族还是学生基本都会备上一台。而且现在的孩子很多都是存在视力问题的,主要的原因就是学习压力太大了,用眼时间过长导致的。所以很多家长选择给孩子使用更为专业的护眼台灯。 不过目前市面上的灯具也是良莠…