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

JAVA八股文第三章(JVM 中如何判断对象可以被回收)

JVM 中如何判断对象可以被回收?(可达性分析彻底讲清)

在 Java 中,我们不需要手动释放内存,因为 JVM 会通过GC(垃圾回收)机制自动回收对象。

但一个核心问题是:

JVM 是如何判断一个对象“可以被回收”的?

这篇文章将从原理到实现,彻底讲清这个问题。


一、核心结论(一句话版)

一个对象如果“无法从 GC Roots 访问到”,就可以被回收

二、两种判断方式(历史 & 现状)

在理论上,有两种判断对象是否存活的方法:


1️⃣ 引用计数法(Reference Counting)❌

原理:
每个对象有一个引用计数器 被引用 → +1 引用失效 → -1 计数为 0 → 可回收

❗ 问题:
无法解决“循环引用”

示例:

Aa=newA();Bb=newB();a.b=b;b.a=a;

👉 结果:

  • a 和 b 互相引用
  • 计数都不为 0
  • 但实际上已经“没用了”

👉结论:Java 不使用引用计数法


2️⃣ 可达性分析(Reachability Analysis)✅

👉 JVM 实际使用的方法


三、什么是可达性分析?

👉 核心思想:

从一组“根对象(GC Roots)”出发, 看对象是否能被访问到

✔ 判断规则:

  • 能访问到 → 存活
  • 访问不到 → 可回收

四、什么是 GC Roots?

👉 GC Roots 是一组“永远不会被回收的起点对象”


常见 GC Roots:

1. 虚拟机栈中的局部变量(引用) 2. 方法区中的静态变量 3. 方法区中的常量 4. 本地方法栈中的引用

👉 简单理解:

GC Roots = 所有“正在使用的入口”

五、判断过程(图解思维)

假设内存中有这样一个结构:

GC Roots → A → B → C D → E(没有任何引用指向)

分析:

  • A、B、C:可以从 GC Roots 访问 → 存活
  • D、E:不可达 → 可回收

👉 本质:

只要断开与 GC Roots 的连接,就会被回收

六、再深入:对象一定会被立即回收吗?

👉 不一定!


对象回收需要两次判断:

✔ 第一次:
是否可达(是否有引用)

✔ 第二次:
是否需要执行 finalize()

finalize 机制:

@Overrideprotectedvoidfinalize()throwsThrowable{// 对象“自救”}

👉 特点:

  • 对象在 finalize 中可以“复活”
  • 只会执行一次
  • 不推荐使用(已逐步废弃)

👉 结论:

即使不可达,也不一定立即回收

七、引用类型(高级面试点)

Java 中不仅有“强引用”,还有 4 种引用类型:


1️⃣ 强引用(Strong Reference)

Objectobj=newObject();

👉 特点:

只要有强引用,就不会被回收

2️⃣ 软引用(Soft Reference)

👉 内存不足时才回收


3️⃣ 弱引用(Weak Reference)

👉 只要发生 GC 就会被回收


4️⃣ 虚引用(Phantom Reference)

👉 用于跟踪对象回收(几乎不用)


八、完整判断流程(总结版)

1. 从 GC Roots 出发进行可达性分析 2. 判断对象是否可达 3. 若不可达 → 标记为“可回收” 4. 判断是否需要执行 finalize 5. 若未“复活” → 最终回收

九、面试高频问题总结

✔ JVM 如何判断对象是否可以被回收?

👉 可达性分析算法


✔ 为什么不用引用计数法?

👉 无法解决循环引用问题


✔ 什么是 GC Roots?

👉 一组作为起点的对象(栈、静态变量等)


✔ 对象一定会被立即回收吗?

👉 不一定(finalize 机制)


✔ 强引用会被回收吗?

👉 不会(只要存在)


十、终极总结

判断对象是否回收的本质: 看它是否“还能被用到”

更技术一点:

是否能从 GC Roots 可达

十一、结语

理解“对象如何被回收”,是掌握 JVM 的关键一步:

  • 想学 GC → 必须懂可达性分析
  • 想优化内存 → 必须懂引用类型
  • 想应对面试 → 这是必考题

如果你能把本文吃透,JVM 内存机制已经迈入进阶阶段。

http://www.jsqmd.com/news/1114085/

相关文章:

  • M极致轻量!思源象棋+zero-native实现轻量桌面应用!
  • C++智能指针深度解析:从unique_ptr到weak_ptr的最佳实践,彻底告别内存泄漏
  • NxDumpTool终极指南:掌握任天堂Switch游戏备份的完整解决方案
  • Python实战:逆向工程中绕过Themida 3.1.8.0反调试技术
  • NLP工程落地实战:面向业务的轻量级规则+模型混合架构
  • B站视频永久保存终极指南:m4s-converter无损合并工具完整解析
  • AI编码效率跃升300%的秘密(ChatGPT代码生成最佳实践白皮书·内部流出版)
  • OpenAI API 国内调用超时、不稳定?原因和企业级解决办法
  • OPENCV——ROCKX+RV1126视频流检测人脸
  • 5分钟解决B站缓存视频无法播放问题:m4s-converter完全使用指南
  • FanControl风扇控制软件:5步解决Windows兼容性问题终极指南 [特殊字符]
  • 从流量分析到威胁狩猎:解码SMTP钓鱼邮件中的Base64攻击载荷
  • Claude Code 释出 Hooks 实战指南,提供 6 个生产级可用配置场景
  • 告别多团队扯皮!上海IT运维+弱电一体化运维服务优势解析
  • 计算机专业就业:大模型时代学生该怎么准备,用排错清单压住复杂度
  • ComfyUI_IPAdapter_plus项目中InsightFace安装问题的终极解决方案
  • MouseTester:免费开源的鼠标性能终极测试解决方案
  • 光学薄膜技术深度解析:从杨氏双缝干涉到悟赫德 AR 镀膜——护景贴观复盾的光学工程实现
  • 从专项到性能:SoloPi实战指南构建APP质量保障体系
  • 解决Linux下802.11ac无线网卡驱动兼容性难题:rtl8812AU_8821AU内核模块深度解析
  • 后端转AI应用开发:33岁转型经验分享,2026年机会与避坑指南(建议收藏)
  • League Akari:让英雄联盟游戏体验更智能高效的全面辅助工具
  • 【JAVA毕设源码分享】基于springboot生日商城的设计与实现(程序+文档+代码讲解+一条龙定制)
  • 微信聊天记录永久保存的终极指南:三步导出完整历史并生成年度报告
  • Axure RP中文语言包:三步告别界面乱码,开启流畅原型设计之旅
  • 奔驰M276/M278链轮异响:冷启动“咔啦啦“,链轮该换了
  • Win11Debloat:你的Windows系统“瘦身教练“,51%性能提升不是梦!
  • 2026年企业级大文件传输新突破:如何选择最适合您的加速工具
  • XSS漏洞攻防全解析:从原理到实战防御与面试要点
  • Linux无线网络新选择:rtl8812AU_8821AU驱动深度解析与实战指南