Java 中垃圾回收机制中如何判断对象需要回收 常见的 GC 回收算法有哪些
2025年Java面试宝典:
链接: https://pan.baidu.com/s/1RUVf75gmDVsg8MQp4yRChg?pwd=9b3g
提取码: 9b3g

一、Java 的垃圾回收机制到底是怎么判断对象该回收的?
大家应该都听说过 Java 的垃圾回收(Garbage Collection, GC),但面试时经常会被问到具体的判断逻辑。这其实涉及到两个核心方法:引用计数法和可达性分析算法。
1. 引用计数法:简单但致命的缺陷
这个方法很简单——给每个对象加一个计数器,记录有多少个地方在引用它。如果计数器归零,说明对象没用了,可以直接回收。
但问题也很明显:循环引用会导致内存泄漏。比如对象 A 引用对象 B,对象 B 又引用对象 A,但两者都不再被外部使用。这时候引用计数永远不为零,但实际已经是垃圾了。

2. 可达性分析算法:JVM 的终极选择
为了解决循环引用的问题,Java 实际采用的是可达性分析算法。简单来说,JVM 会从一组 GC Roots(比如虚拟机栈中的局部变量、静态变量等)出发,遍历所有对象引用链。如果某个对象无法通过这些根节点到达,就会被标记为可回收。
举个栗子🌰:你创建了一个对象 A,当方法执行完,栈帧里的局部变量被销毁,A 就和 GC Roots 断了联系,自然就成了垃圾。
二、常见的 GC 回收算法有哪些?
现在你知道怎么判断垃圾了,接下来就是“怎么收垃圾”。这里要重点掌握四种算法,很多大厂面试官会追问它们的优缺点。
1. 标记-清除算法(Mark-Sweep)
过程:
- 先标记所有需要回收的对象
- 再统一回收这些对象
缺点:
- 会产生内存碎片(就像拼图缺了一块,导致大对象无法分配)
- 效率不稳定,堆越大标记和清除时间越长

2. 复制算法(Copying)
核心思想:把内存分成两块,每次只用其中一块。当这一块用完了,就把存活的对象复制到另一块,然后清空当前区域。
优点:
- 没有内存碎片问题
- 适合对象存活率低的场景(比如新生代的 Eden 区)
缺点:
- 内存利用率只有一半(太奢侈了!)
3. 标记-整理算法(Mark-Compact)
这是标记-清除算法的升级版。先标记可回收对象,然后把存活的对象都“压缩”到内存一端,最后清理边界外的空间。
优点:
- 解决了内存碎片问题
- 适合老年代这种存活率高的区域
缺点:
- 整理过程需要移动对象,会影响性能
4. 分代收集算法(Generational Collection)
这才是 Java 的实际选择!JVM 把堆内存分为新生代和老年代,针对不同区域采用不同算法:
- 新生代:对象存活率低,用复制算法(比如 HotSpot 的 Eden + Survivor 区)
- 老年代:对象存活率高,用标记-清除或标记-整理算法
三、如何用“人话”在面试中讲清楚这些?
面试官问这个问题时,其实是想知道:
- 你理解 GC 的基本原理
- 你知道不同场景下的算法选择依据
这里分享一个口述模板:
“Java 的垃圾回收主要靠可达性分析算法,从 GC Roots 出发检查对象是否可达。常见的算法中,分代收集是综合最优解——新生代用复制算法解决高频回收的问题,老年代用标记-整理减少内存碎片。比如我们在优化 Full GC 频率时,就需要关注老年代的空间分配策略……”
需要面试鸭会员的朋友,可以通过面试鸭返利网联系我,购买后可返利 25元!现在注册还能免费领取面试题库哦~


