GC Roots 是可达性分析的起点集合,从这些节点出发引用链可达的对象判定为存活。可以作为 GC Roots 的主要有四类:
第一,虚拟机栈(栈帧的局部变量表)中引用的对象——即当前线程正在执行的方法的参数、局部变量所引用的对象,这是最常见的一类。
第二,方法区中类静态属性引用的对象——如 static Object obj = ... 持有的引用;以及常量引用的对象,如字符串常量池里的引用。
第三,本地方法栈中 JNI 引用(Native 方法引用的对象)。
第四,JVM 内部引用——如基本数据类型对应的 Class 对象、常驻异常对象(OOM、NPE 等)、系统类加载器;还有被 synchronized 持有的同步锁对象,以及 Java 虚拟机自身的一些数据结构(如 JNI 全局引用、JMX 相关引用)。
要点:局部变量随方法出栈失效,所以长生命周期容器中残留的对象(缓存、监听器)是泄漏高发区。Java 8 起局部变量对对象的引用在字节码作用域结束后不再阻止回收(与 JIT 激进程度有关),这解释了一些"对象提前被回收"的现象。
追问方向:四种引用类型(强、软、弱、虚)与 GC 的关系?
(约 350 字)