GC Roots 是一组必须活跃的引用。用通俗的话来说,就是程序接下来通过直接引用或者间接 引用,能够访问到的潜在被使用的对象。

GC Roots 包括:

Java 线程中,当前所有正在被调用的方法的引用类型参数、局部变量、临时值等。也就是与我 们栈帧相关的各种引用。

所有当前被加载的 Java 类。

Java 类的引用类型静态变量。

运行时常量池里的引用类型常量(String 或 Class 类型)。

JVM 内部数据结构的一些引用,比如 sun.jvm.hotspot.memory.Universe 类。

用于同步的监控对象,比如调用了对象的 wait() 方法。

JNI handles,包括 global handles 和 local handles。

这些 GC Roots 大体可以分为三大类,下面这种说法更加好记一些:

活动线程相关的各种引用。

类的静态变量的引用。

JNI 引用。

有两个注意点:

我们这里说的是活跃的引用,而不是对象,对象是不能作为 GC Roots 的。

GC 过程是找出所有活对象,并把其余空间认定为“无用”;而不是找出所有死掉的对象,并回 收它们占用的空间。所以,哪怕 JVM 的堆非常的大,基于 tracing 的 GC 方式,回收速度也会 非常快。