📌 PDF :大白话说Java面试题 --- 02-JVM篇
第14题:什么是可达性分析算法
📚 回答:
- 核心流程 :
可达性分析算法是 JVM 垃圾回收的核心机制之一,用于标记内存中的存活对象和垃圾对象。
1. GC Roots 的定义与作用
-
定义:
- GC Roots 是一组特殊的对象,作为可达性分析的起点。
- 它们包括以下几种类型:
- 静态变量 :被
static修饰的变量。 - 局部变量:方法中的参数或局部变量。
- 常量:字符串常量池中的常量。
- JNI 引用:本地方法(Native Method)中的引用。
- 静态变量 :被
-
作用:
- GC Roots 是垃圾回收的起点,只有从这些根节点能够直接或间接引用的对象才被认为是存活的。
2. 可达性分析的过程
-
步骤详解 :
-
从 GC Roots 出发:
- JVM 会从所有的 GC Roots 开始遍历,找到所有直接引用的对象。
-
递归搜索:
- 对于每个直接引用的对象,继续查找它们引用的其他对象,直到所有可达对象都被标记为存活。
-
标记垃圾对象:
- 无法从 GC Roots 到达的对象被视为垃圾对象,等待被回收。
💡 图示说明 :
以下是一个简单的可达性分析过程的示意图:
GC Roots
↓
Object A → Object B → Object C
↓
Object D → Object E -
-
在这个例子中,
Object A、B、C、D和E都是从 GC Roots 可达的,因此它们是存活对象。 -
如果某个对象(如
Object F)没有任何引用指向它,则它是不可达的,会被标记为垃圾对象。
3. 源码解析
- HotSpot VM 实现 :
- 可达性分析算法在 HotSpot VM 中由
Mark-Sweep或Mark-Compact算法实现。 - 具体逻辑可以参考
GenCollectedHeap和ConcurrentMarkSweepGeneration模块。
- 可达性分析算法在 HotSpot VM 中由
4. 总结对比
| 特性 | 可达性分析算法 |
|---|---|
| 适用场景 | 判断对象是否存活,标记垃圾对象 |
| 优点 | 解决循环引用问题,适用于复杂对象图 |
| 缺点 | 遍历开销较大,可能导致 STW 时间较长 |
💡 代码示例 :
以下代码展示了可达性分析的基本思想:
java
// 示例:模拟可达性分析
class GCRoots {
static Object staticObj = new Object(); // 静态变量
Object instanceObj = new Object(); // 实例变量
}
public class ReachabilityAnalysis {
public static void main(String[] args) {
GCRoots roots = new GCRoots();
Object localObj = new Object(); // 局部变量
// 这些对象都是从 GC Roots 可达的
System.out.println("GC Roots: " + roots.staticObj + ", " + roots.instanceObj + ", " + localObj);
// 当没有引用指向某个对象时,它将成为垃圾对象
localObj = null;
}
}