一文讲透 JVM 内存回收:GC Roots 与可达性分析如何决定对象生死

发布时间:2026/11/5 1:51:46
一文讲透 JVM 内存回收:GC Roots 与可达性分析如何决定对象生死

一文讲透 JVM 内存回收:GC Roots 与可达性分析如何决定对象生死

【免费下载链接】jvm🤗 JVM 底层原理最全知识总结项目地址: https://gitcode.com/gh_mirrors/jvm9/jvm

jvm 项目系统梳理了 JVM 底层原理,这篇聚焦 JVM 内存回收的判定核心——GC Roots 与可达性分析,讲清 JVM 如何判断对象存活,以及 Java 内存泄漏怎么排查。

🔍 泄漏现场复盘:GC 凭什么判定对象该死

先还原一个高频事故:服务跑了几周,堆被某个缓存 Map 一点点占满,GC 越来越频繁,最后 OOM。dump 出来发现对象"明明没人用",虚拟机为什么不动手?

关键在于可达性分析:虚拟机不数引用个数,而是从一组固定起点出发,沿引用链往下找——凡是还能找到的都算活着,找不到的才是垃圾。判定标准就这一条:与 GC Roots 直接或间接相连即存活,否则可回收。

那个缓存 Map 收不掉,是因为它挂在 static 字段上,起点直接够得着。而 GC Roots 刻意不含"堆对象之间的互相引用",所以两个对象互相指着对方也照样会被判死,循环引用在这套机制下天然不成立。

从哪查起:GC Roots 的四大锚点怎么定

把 JVM 想成一张电网:GC Roots 是四个总开关接出的干线,对象是干线上的设备,引用就是电线。巡检只从干线往沿线查——供电还连得上的设备继续运行,与干线彻底断开的孤岛设备,一律判废回收。技术翻译:这四个起点是虚拟机规定死的,可达性遍历只能从这里发起。

  • 虚拟机栈的本地变量表:当前栈帧里的参数和局部变量
  • 本地方法栈:JNI 调用中 native 方法持有的引用
  • 方法区的常量引用:比如字符串常量池中的常量
  • 方法区的静态属性:类 static 字段指向的对象

再强调一次关键事实:堆对象互相引用不算锚点,这正是循环引用能被正确回收的原因。

⚡ 标记三步走:一次"点名"如何完成(STW 何时发生)

巡检不能把全厂拉闸半天,所以标记拆成三段:

  1. 初始标记:先拉闸(STW,Stop The World),只标 GC Roots 直接挂着的对象,动作很快
  2. 并发标记:恢复供电,巡检队与用户线程同时跑,顺着引用链把可达对象全部标一遍
  3. 重新标记:并发期间用户线程仍在改引用,再短暂拉闸(STW)复核,修正漏标和错标

四种引用强度:存活门槛分别是什么

JDK 1.2 之后,引用分成四档,"能活着"的门槛各不相同:

  • 强引用:最常见的Object obj = new Object();,只要引用还在就不会被回收
  • 软引用:用 SoftReference 持有时,内存充足就保留,堆吃紧才回收——典型场景是缓存
  • 弱引用:用 WeakReference 持有时,下一轮 GC 就收,不看内存余量——适合可有可无的辅助数据
  • 虚引用:用 PhantomReference 时完全挡不住回收,只用来感知"对象已被回收",常配合直接内存做释放跟踪

判"死刑"前的一次机会:finalize 复活机制

被标成不可达的对象不会立刻消失。若它重写了 finalize() 且尚未执行过,会先进入 F-Queue 队列,由低优先级线程执行该函数;在里面把 this 重新挂到某个引用上(obj = this;),对象就回到可达状态,复活成功,但机会只有一次。没重生的对象,要到下一轮 GC 才会被彻底清除。

📋 内存泄漏避坑清单:5 项自查

  • static 字段别当"永久停车场",临时对象挂上去就收不掉
  • 集合用完及时 clear() 或置 null,Map 的 key 尤其注意
  • 监听器、回调注册后要反注册,否则生命周期跟着宿主走
  • 缓存优先 SoftReference / WeakReference,给 GC 留后路
  • dump 后用工具从 GC Roots 反查大对象,定位"谁指住了它"

至此,从起点、标记到引用分档,JVM 内存回收的判定逻辑就完整了:GC 从不猜测,只认"能不能从 GC Roots 连上"。日常开发中分清四档引用强度、避开上面这些坑,绝大多数 Java 内存泄漏都能在一次 dump 里定位到根源。想继续深入,可阅读项目内的 GC 算法文档、内存分配与回收策略 与 HotSpot 收集器文档。

【免费下载链接】jvm🤗 JVM 底层原理最全知识总结项目地址: https://gitcode.com/gh_mirrors/jvm9/jvm

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考