JVM面试题解,垃圾回收之“对象存活判断”剖析

一、JVM怎么判断一个类/对象是不是垃圾?

先来说如何判断一个对象是不是垃圾

最常用的就是引用计数法可达性分析

引用计数法

引用计数法为每个对象维护一个计数器来跟踪有多少个引用指向该对象。每当创建一个新的引用指向某个对象时,计数器加1;每当一个引用失效或被移除时,计数器减1。当计数器降为0时,表示没有其他对象引用它,因此可以安全地将其回收。

引用计数法有个非常大的问题就是循环引用。

循环引用:如果两个或多个对象相互引用形成环状结构,即使这些对象不再被外部使用,它们的引用计数也不会降为0,从而导致内存泄漏。例如,A持有B的引用,B也持有A的引用,但没有任何其他对象引用A或B,这时它们应该被回收,但由于相互引用,它们的引用计数都不会降为0。

那么如果采用了引用计数法,如何解决循环引用呢? 引入弱引用来打破循环引用链。弱引用不会增加对象的引用计数,因此当一个对象仅通过弱引用保持时,它可以被垃圾回收器回收。

可达性分析

可达性分析就是用来判定对象是否存活的。

这个算法的基本思路就是通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到 GC Roots 没有任何引用链相连时,则证明此对象是不可用的。

二、说到GC ROOTS,你知道Java中哪些对象可作为GC ROOTS吗?

作为 GC Roots 的对象包括下面几种(重点是前面 4 种):

  • 虚拟机栈(栈帧中的本地变量表)中引用的对象;各个线程调用方法堆栈中使用到的参数、局部变量、临时变量等。
  • 方法区中类静态属性引用的对象;java 类的引用类型静态变量。
  • 方法区中常量引用的对象;比如:字符串常量池里的引用。
  • 本地方法栈中 JNI(即一般说的 Native 方法)引用的对象。
  • JVM 的内部引用( class 对象、异常对象 NullPointException 、 OutofMemoryError ,系统类加载器)。(非重点)
  • 所有被同步锁( synchronized )持有的对象。(非重点)
  • JVM 内部的 JMXBean 、 JVMTI 中注册的回调、本地代码缓存等(非重点)
  • JVM 实现中的“临时性”对象,跨代引用的对象(在使用分代模型回收时只回收部分代的对象)(非重点)

除了这些固定的 GC Roots 集合以外,跟进用户选用的垃圾回收器以及当前回收的内存区域不同,还可能会有其他对象"临时"加入成为 GC Roots 。

三、对象不可达是不是立即被回收死亡?

即使通过可达性分析判断不可达的对象,也不是“非死不可”,它还会处于“缓刑”阶段,真正要宣告一个对象死亡,需要经过两次标记过程

  • 一次是没有找到与 GCRoots 的引用链,它将被第一次标记。
  • 随后进行一次筛选(如果对象覆盖了 finalize ),我们可以在 finalize 中去拯救,俗称对象的自我救赎。

finalize()方法的工作原理

  1. 标记阶段:当垃圾回收器开始运行时,它首先会进行一次可达性分析,找出所有不可达的对象。

  2. Finalization队列:对于那些实现了finalize()方法且尚未被调用过finalize()的不可达对象,JVM不会直接回收它们,而是将这些对象放入一个称为finalization队列的数据结构中。

  3. 调用finalize():随后,一个专门的Finalizer线程会从finalization队列中取出对象,并调用它们的finalize()方法。这为对象提供了一个最后的机会来执行清理代码或甚至重新与程序中的其他部分建立联系(虽然这种做法不推荐)。

  4. 第二次可达性分析:在finalize()方法执行完毕后,垃圾回收器会对这些对象再次进行可达性分析。如果此时这些对象仍然不可达,那么它们将会被真正地回收;否则,如果finalize()方法使对象重新变得可达(例如通过将自身赋值给某个静态变量或全局变量),则该对象就不会被回收。

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

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

相关文章

【Django开发】django美多商城项目完整开发4.0第14篇:Docker使用,1. 在Ubuntu中安装Docker【附

本教程的知识点为: 项目准备 项目准备 配置 1. 修改settings/dev.py 文件中的路径信息 2. INSTALLED_APPS 3. 数据库 用户部分 图片 1. 后端接口设计: 视图原型 2. 具体视图实现 用户部分 使用Celery完成发送 判断帐号是否存在 1. 判断用户名是否存在 后…

14-5C++的deque容器

(一)deque的基础知识 1.deque是“double-ended queue"的缩写和vector-样都是STL的容器 2.deque是双端数组而vector是单端的 3.deque在接口上和vector非常相似,在许多操作的地方可以直接替换 4.deque可以随机存取元素(支持索引值直接存取&#xf…

鸿蒙仓颉环境配置(仓颉SDK下载,仓颉VsCode开发环境配置,仓颉DevEco开发环境配置)

目录 ​1)仓颉的SDK下载 1--进入仓颉的官网 2--点击图片中的下载按钮 3--在新跳转的页面点击即刻下载 4--下载 5--找到你们自己下载好的地方 6--解压软件 2)仓颉编程环境配置 1--找到自己的根目录 2--进入命令行窗口 3--输入 envsetup.bat 4--验证是否安…

grafana新增email告警

选择一个面板 比如cpu 新增一个临界点表达式 input选A 就是A的值达到某个临界点 触发告警 我这边IS ABOVE0.15就是cpu大于0.15%就触发报警,这个值怎么填看指标的值显示 这里要设置一下报警条件 这边随便配置下 配置标签和通知,选择你的邮件 看下告警…

springboot自动配置原理(高低版本比较)spring.factories文件的作用

SpringBootApplication public class SpringSecurityApplication {public static void main(String[] args) {SpringApplication.run(SpringSecurityApplication.class, args);}}注解SpringBootApplication Target({ElementType.TYPE}) Retention(RetentionPolicy.RUNTIME) Doc…

Spring源码03 - bean注入和生命周期

bean注入和生命周期(面试) 文章目录 bean注入和生命周期(面试)一:getBean的主体思路1:初步思路2:SpringBean的主体思路 二:Spring如何解决循环依赖问题1:三级Map&#xf…

vscode导入模块不显示类型注解

目录结构: utils.py: import random def select_Jrandom(i:int, m:int) -> int:"""随机选择一个不等于 i 的整数"""j iwhile j i:j int(random.uniform(0, m))return jdef clip_alpha(alpha_j:float, H:float, L:f…

浅谈机器学习之基于RNN进行充值的油费预测

浅谈机器学习之基于RNN进行充值的油费预测 引言 随着智能交通和物联网技术的发展,油费预测已成为研究的热点之一。准确的油费预测不仅能帮助车主合理规划出行成本,还可以为油价波动提供参考依据。近年来,递归神经网络(RNN&#…

There is no getter for property named ‘XXX’ in ‘XXXX‘

写了一个POST方法用于新增软件描述信息,报错显示在我的实体类中没有这个属性的getter方法,实体类如下: 报错没有softWare这个属性的getter方法,但是我的实体类中本来就没有这个属性(笑哭...) 后面查了许多资料发现&am…

基于springboot+vue的校园二手物品交易系统的设计与实现

开发语言:Java框架:springbootJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:…

H266/VVC 变换编码中大尺寸变换块高频系数置零技术

大尺寸变换块高频系数置零 近年来视频技术有了飞速的变化,视频的分辨率从 1080P 过渡到 4K,并逐渐向发展 8K。为了适应日益增长的视频分辨率,新的编码技术采用了更大尺寸的变换块来提高编码效率,最大变换块大小变成 64x64。变换块…

5989.数字接龙

5989.数字接龙 小蓝最近迷上了一款名为《数字接龙》的迷宫游戏,游戏在一个大小为 NN 的格子棋盘上展开,其中每一个格子处都有着一个 0…K−10…K−1 之间的整数。 游戏规则如下: 从左上角 (0,0) 处出发,目标是到达右下角 (N−1…

Titans: 学习在测试时记忆 - 论文解读与总结

论文地址:https://arxiv.org/pdf/2501.00663v1 本文介绍了一篇由 Google Research 发表的关于新型神经网络架构 Titans 的论文,该架构旨在解决传统 Transformer 在处理长序列时的局限性。以下是对论文的详细解读,并结合原文图片进行说明&…

账号IP属地:依据手机号还是网络环境?

在数字化生活中,账号的IP属地信息往往成为我们关注的一个焦点。无论是出于安全考虑,还是为了满足某些特定服务的需求,了解账号IP属地的确定方式都显得尤为重要。那么,账号IP属地根据手机号还是网络来确定的呢?本文将深…

微信小程序实现自定义日历功能

文章目录 1. 创建日历组件实现步骤:2. 代码实现过程3. 实现效果图4. 关于作者其它项目视频教程介绍 1. 创建日历组件实现步骤: 创建日历组件:首先,你需要创建一个日历组件,包含显示日期的逻辑。样式设计:为…

YOLOv9改进,YOLOv9检测头融合RFAConv卷积,适合目标检测、分割任务

摘要 空间注意力已广泛应用于提升卷积神经网络(CNN)的性能,但它存在一定的局限性。作者提出了一个新的视角,认为空间注意力机制本质上解决了卷积核参数共享的问题。然而,空间注意力生成的注意力图信息对于大尺寸卷积核来说是不足够的。因此,提出了一种新型的注意力机制—…

【机器学习】深入无监督学习分裂型层次聚类的原理、算法结构与数学基础全方位解读,深度揭示其如何在数据空间中构建层次化聚类结构

🌟个人主页:落叶 🌟当前专栏: 机器学习专栏 目录 引言 分裂型层次聚类(Divisive Hierarchical Clustering) 1. 基本原理 2. 分裂型层次聚类的算法步骤 Step 1: 初始化 Step 2: 选择分裂的簇 Step 3: 执行分裂操作…

VirtualBox can‘t enable the AMD-V extension

个人博客地址:VirtualBox cant enable the AMD-V extension | 一张假钞的真实世界 最近一次完成Deepin的系统更新后,进入VirtualBox创建的虚拟机(Widows10)时,出现以下错误: 根据网址“https://askubuntu.…

[JavaScript] 数组与对象详解

文章目录 数组(Array)什么是数组数组的常用操作**访问数组元素****修改数组元素****数组的长度****添加和删除元素** 常用数组方法map():filter():reduce():**其他实用方法** 对象(Object)什么是对象对象的基本操作**访问属性****…

“模板”格式化发布新创诗(为《诗意 2 0 2 5》贡献力量)

预置MarkDown&Html文本,脚本读取f-string模板完成录入嵌套。 (笔记模板由python脚本于2025-01-22 19:19:58创建,本篇笔记适合喜欢分享的达人的coder翻阅) 【学习的细节是欢悦的历程】 博客的核心价值:在于输出思考与经验,而不…