JVM 垃圾回收器是如何判断一个对象是否要回收?

JVM 垃圾回收器(Garbage Collector)需要判断哪些对象是“垃圾”,即不再被程序使用的对象,以便回收它们占用的内存。JVM 主要使用以下两种方法来判断对象是否是垃圾:

1. 引用计数算法 (Reference Counting):

  • 原理:

    • 为每个对象维护一个引用计数器。
    • 当一个对象被引用时,引用计数器加 1。
    • 当一个对象的引用被置为 null 或超出作用域时,引用计数器减 1。
    • 当一个对象的引用计数器为 0 时,表示该对象不再被任何地方引用,可以被回收。
  • 优点:

    • 实现简单: 只需要维护一个计数器。
    • 实时性高: 当对象的引用计数器变为 0 时,可以立即回收该对象。
  • 缺点:

    • 无法解决循环引用问题: 如果两个或多个对象相互引用,即使它们不再被其他对象引用,它们的引用计数器也不会变为 0,导致无法回收。
    public class ReferenceCountingGC {public Object instance = null;public static void main(String[] args) {ReferenceCountingGC objA = new ReferenceCountingGC();ReferenceCountingGC objB = new ReferenceCountingGC();objA.instance = objB; // objA 引用 objBobjB.instance = objA; // objB 引用 objAobjA = null; // objA 不再引用对象objB = null; // objB 不再引用对象// 此时,objA 和 objB 相互引用,引用计数器都不为 0,无法被回收 (即使它们已不再被使用)// ...}
    }
    
  • HotSpot VM 是否使用: HotSpot VM 不使用引用计数算法,因为它无法解决循环引用问题。

2. 可达性分析算法 (Reachability Analysis) (根搜索算法):

  • 原理:

    • 从一组称为 “GC Roots” 的根对象开始,沿着对象引用链进行遍历。
    • 如果一个对象到 GC Roots 之间没有任何引用链相连,则说明该对象不可达,可以被回收。
    • 可达的对象会被标记, 不可达的对象被认为是垃圾.
  • GC Roots:

    • 虚拟机栈 (VM Stack) 中引用的对象: 局部变量、方法参数等引用的对象。
    • 方法区中类静态属性引用的对象: static 变量引用的对象。
    • 方法区中常量引用的对象: final 修饰的常量引用的对象。
    • 本地方法栈中 JNI (Java Native Interface) 引用的对象: Native 方法引用的对象。
    • Java 虚拟机内部的引用: 例如, 基本数据类型对应的 Class 对象, 一些常驻的异常对象(NullPointerException, OutOfMemoryError 等), 系统类加载器.
    • 被同步锁 (synchronized 关键字) 持有的对象。
    • 反应Java虚拟机内部情况的 JMXBean、JVMTI 中注册的回调、本地代码缓存等。
  • 优点:

    • 可以解决循环引用问题。
    • 准确性高。
  • 缺点:

    • 需要暂停应用程序 (Stop-The-World): 在进行可达性分析时,需要暂停所有 Java 线程,以保证分析结果的准确性。
    • 实现复杂。
  • HotSpot VM 是否使用: HotSpot VM 使用可达性分析算法

对象死亡的判定 :

即使通过可达性分析算法判断一个对象不可达,它也不会立即被回收。对象真正死亡需要经历至少两次标记过程:

  1. 第一次标记:

    • 如果对象在进行可达性分析后发现没有与 GC Roots 相连接的引用链,则会被第一次标记。
    • 会进行筛选, 判断此对象是否有必要执行 finalize() 方法。
    • 如果对象没有覆盖 finalize() 方法,或者 finalize() 方法已经被虚拟机调用过,则会被判定为“没有必要执行”。
    • 如果对象覆盖了 finalize() 方法, 且还没有被调用过, 则会将该对象放置在一个名为 F-Queue 的队列中。
  2. finalize() 方法的执行 (如果有):

    • 稍后由一条由虚拟机自动建立的、低调度优先级的 Finalizer 线程去执行它们的 finalize() 方法。
    • 注意:
      • finalize() 方法是对象逃脱死亡的最后一次机会。
      • finalize() 方法中,只要将对象重新与引用链上的任何一个对象建立关联(例如,将 this 赋值给某个类变量或对象的成员变量),就可以避免被回收。
      • finalize() 方法只会被系统自动调用一次。如果对象在 finalize() 方法中逃脱了死亡,下次再被标记时,finalize() 方法不会再被执行。
      • 不建议使用 finalize() 方法进行资源释放,因为它的执行时间不确定,可能会导致资源长时间得不到释放。
      • finalize 方法可能会导致性能问题,应尽量避免使用。
  3. 第二次标记:

    • 如果在 finalize() 方法中对象成功逃脱了死亡,则不会被回收。
    • 如果在 finalize() 方法中对象没有逃脱死亡,或者对象没有覆盖 finalize() 方法,或者 finalize() 方法已经被虚拟机调用过,则会被第二次标记。
    • 被第二次标记的对象会被放置在一个名为 F-Queue 的队列中, 等待被回收.

总结:

JVM 使用可达性分析算法来判断对象是否是垃圾。从 GC Roots 开始,沿着对象引用链进行遍历,如果一个对象到 GC Roots 之间没有任何引用链相连,则说明该对象不可达,可以被回收。即使对象不可达,也不会立即被回收,需要经历至少两次标记过程,并且有机会在 finalize() 方法中逃脱死亡。

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

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

相关文章

kali——httrack

目录 前言 使用教程 前言 HTTrack 是一款运行于 Kali Linux 系统中的开源网站镜像工具,它能将网站的页面、图片、链接等资源完整地下载到本地,构建出一个和原网站结构相似的离线副本。 使用教程 apt install httrack //安装httrack工具 httrac…

kotlin函数类型

一 函数类型定义 1 定义 函数类型就是 (Int, Int) -> Int 函数类型其实就是将函数的 “参数类型” 和 “返回值类型” 抽象出来 2 示例 : (Int, Int) -> Int 表示接收两个 Int 参数并返回 Int 的函数类型; (String) -> Unit 表示接收 Strin…

C# Winform 入门(9)之如何封装并调用dll

封装dll 首先创建 .Net平台 类库 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace _09.Encapsulation_dll {public class Program{/// <summary>/// 求两个double类型的数值的和/// &l…

前后端分离下,Spring Boot 请求从发起到响应的完整执行流程

以下是前后端分离架构下&#xff0c;Spring Boot 请求从发起到响应的完整执行流程&#xff0c;结合你提出的所有问题&#xff0c;按真实执行顺序和职责链条重新整理所有核心概念、结构、关键类、数据转换点和典型代码示例&#xff1a; 一、前端发起请求&#xff08;步骤1-2&…

基于sklearn实现文本摘要思考

和各位小伙伴分享一下使用sklearn进行文本摘要的思考。 第一版本 原理 提取式文本摘要的基本原理是&#xff1a; 将文本分割成句子 计算每个句子的重要性(权重) 选择权重最高的几个句子组成摘要 常用的句子权重计算方法&#xff1a; TF-IDF&#xff1a;基于词频-逆文档频…

OpenHarmony子系统开发 - DFX(三)

OpenHarmony子系统开发 - DFX&#xff08;三&#xff09; 五、HiTraceMeter开发指导 HiTraceMeter概述 简介 HiTraceMeter在OpenHarmony中&#xff0c;为开发者提供业务流程调用链跟踪的维测接口。通过使用该接口所提供的功能&#xff0c;可以帮助开发者迅速获取指定业务流…

2025年 能够有效提升AI的生成质量和逻辑严谨性 的通用型系统提示

以下是三个经过精心设计的通用型系统提示&#xff08;System Prompt&#xff09;&#xff0c;能够有效提升AI的生成质量和逻辑严谨性&#xff0c;适用于各类对话、分析和创作场景&#xff1a; Prompt 1 - 专家级分步验证模式 你是一个具备跨领域知识整合能力的超级AI&#xff…

python爬虫:小程序逆向实战教程

根据我之前发表的文章&#xff0c;我们进行延伸实战https://blog.csdn.net/weixin_64809364/article/details/146981598?spm1001.2014.3001.5501 1. 想要爬取什么小程序&#xff0c;我们进行搜索 2. 找到我们vx小程序的文件地址&#xff0c;我们就可以进行破解 破解步骤强看…

C语言变长数组(VLA)详解:灵活处理动态数据的利器

引言 在C语言中&#xff0c;传统的数组大小必须在编译时确定&#xff0c;这限制了程序处理动态数据的灵活性。C99标准引入的变长数组&#xff08;Variable-Length Array, VLA&#xff09; 打破了这一限制&#xff0c;允许数组长度在运行时动态确定。本文将深入解析VLA的语法、…

串口数据转换为IP数据

串口数据转换为IP数据是一种常见的通信技术,用于将传统的串行设备(如传感器、控制器等)接入现代的IP网络。以下是详细介绍: 1. 转换原理 串口数据转换为IP数据的过程涉及硬件和软件的结合,核心是将串行数据封装为TCP/IP或UDP/IP数据包,通过网络传输。具体步骤如下: 硬…

client-go如何监听自定义资源

如何使用 client-go 监听自定义资源 在 Kubernetes 中使用 client-go 监听自定义资源&#xff08;Custom Resource&#xff0c;简称 CR&#xff09;需要借助 Dynamic Client 或 Custom Informer&#xff0c;因为 client-go 的标准 Clientset 只支持内置资源&#xff08;如 Pod…

C++软件开发架构

文章目录 1.全局消息通信MsgHandler.h单元测试(QTest)MsgHandlerUnitTest.hMsgHandlerUnitTest.cpp 2.实例间通信InstMsgHandler.h单元测试InstMsgHandlerUnitTest.hInstMsgHandlerUnitTest.cpp 1.全局消息通信 1. 适用于类与类单个对象实例之间的通信&#xff0c;多个对象需要…

AI Agent设计模式一:Chain

概念 &#xff1a;线性任务流设计 ✅ 优点&#xff1a;逻辑清晰易调试&#xff0c;适合线性处理流程❌ 缺点&#xff1a;缺乏动态分支能力 from typing import TypedDictfrom langgraph.graph import StateGraph, END# 定义后续用到的一些变量 class CustomState(TypedDict):p…

Git三剑客:工作区、暂存区、版本库深度解析

一、引言&#xff1a;为什么需要理解Git的核心区域&#xff1f; 作为开发者&#xff0c;Git是日常必备的版本控制工具。但你是否曾因以下问题感到困惑&#xff1f; 修改了文件&#xff0c;但 git status 显示一片混乱&#xff1f; git add 和 git commit 到底做了什么&#x…

Python数据类型-list

列表(List)是Python中最常用的数据类型之一&#xff0c;它是一个有序、可变的元素集合。 1. 列表基础 创建列表 empty_list [] # 空列表 numbers [1, 2, 3, 4, 5] # 数字列表 fruits [apple, banana, orange] # 字符串列表 mixed [1, hello, 3.14, True] # 混合类型…

Keepalive+LVS+Nginx+NFS高可用项目

项目架构 分析 主机规划 主机系统安装应用网络IPclientredhat 9.5无NAT172.25.250.115/24lvs-masterrocky 9.5ipvsadm&#xff0c;keepalivedNAT172.25.250.116/24 VIP 172.25.250.100/32lvs-backuprocky 9.5ipvsadm&#xff0c;keepalivedNAT172.25.250.117/24 VIP 172.25.2…

【视觉与语言模型参数解耦】为什么?方案?

一些无编码器的MLLMs统一架构如Fuyu&#xff0c;直接在LLM内处理原始像素&#xff0c;消除了对外部视觉模型的依赖。但是面临视觉与语言模态冲突的挑战&#xff0c;导致训练不稳定和灾难性遗忘等问题。解决方案则是通过参数解耦方法解决模态冲突。 在多模态大语言模型&#xf…

AI比人脑更强,因为被植入思维模型【43】蝴蝶效应思维模型

giszz的理解&#xff1a;蝴蝶效应我们都熟知&#xff0c;就是说一个微小的变化&#xff0c;能带动整个系统甚至系统的空间和时间的远端&#xff0c;产生巨大的链式反应。我学习后的启迪&#xff0c;简单的说&#xff0c;就是不要忽视任何微小的问题&#xff0c;更多时候&#x…

AI 数理逻辑基础之统计学基本原理(上)

目录 文章目录 目录统计学统计学基本概念描述性统计数据可视化图表工具 汇总统计统计数据的分布情况&#xff1a;中位数、众数、平均值统计数据的离散程度&#xff1a;极差、方差、标准差、离散系数 相关分析Pearson 线性关系相关系数Spearman 单调关系相关系数 回归分析回归模…

无招回归阿里

这两天&#xff0c;无招回归阿里的新闻被刷屏了。无招创业成立的两氢一氧公司无招的股份也被阿里收购&#xff0c;无招以这种姿态回归阿里&#xff0c;并且出任钉钉的 CEO。有人说&#xff0c;这是对 5 年前“云钉一体”战略的纠偏。现在确实从云优先到 AI 优先&#xff0c;但云…