你好,我是风一样的树懒,一个工作十多年的后端开发,曾就职京东、阿里等多家互联网头部企业。
在 Java 的垃圾回收机制(Garbage Collection)中,GC Root(根对象) 是一个非常重要的概念。它定义了 Java 虚拟机(JVM)中哪些对象作为垃圾回收的起点,从这些根对象出发,可以找到所有被引用的对象。
Java 栈(虚拟机栈)中的引用
任何正在执行的线程中的局部变量或方法参数。
这些引用通常存储在栈帧中的局部变量表中。
方法区中的静态变量
定义在类中的 static 变量,例如:static String str = "Hello";。
这些变量在类加载时存储在方法区中(Java 8 后存储在元空间)。
方法区中的常量引用
比如常量池中的引用,字符串常量(如 "abc")或被引用的 final 常量。
常量池在方法区中存在,因此常量池的引用也属于 GC Root。
本地方法栈中的 JNI 引用
通过本地方法(如 C、C++ 代码)创建的对象引用,例如 JNIEnv 指针。
活动线程
所有存活的线程对象。
类加载器
加载类的类加载器本身可能作为根。
JVM 内部的特殊引用
如 JVM 中用于垃圾回收或运行时的一些特殊对象(系统类加载器、反射调用中创建的对象等)。
引用链:对象之间的引用关系。
标记-清除过程:
在垃圾回收过程中,所有可达的对象被标记为存活对象。
未被标记的对象会被认为是垃圾,清除这些对象并释放其占用的内存。
public class GCRootExample {
private static GCRootExample instance;
public static void main(String[] args) {
// 静态变量作为 GC Root
instance = new GCRootExample();
// 方法局部变量作为 GC Root
GCRootExample localVar = new GCRootExample();
// 调用垃圾回收
System.gc();
}
}
instance 是静态变量,作为 GC Root。
localVar 是局部变量,存储在栈中,也作为 GC Root。
以 instance 和 localVar 为起点,找到的所有引用对象会被标记为可达对象。
垃圾回收的核心:GC Root 是垃圾回收的起点,决定了哪些对象会被清理,哪些会被保留。
性能优化:合理设计 GC Root 的引用关系,能够提高垃圾回收的效率,减少内存泄漏。
调试和分析:通过工具(如 VisualVM 或 MAT)分析 GC Root,可以帮助找到内存泄漏的根源。
GC Root 是可达性分析的起点,它是 JVM 判定对象是否存活的核心。
GC Root 的主要来源包括栈中的引用、静态变量、常量引用、JNI 引用等。
GC Root 的引用链连接的对象会被认为是存活对象,不会被垃圾回收。
今天的内容就分享到这儿,喜欢的朋友可以关注,点赞。有什么不足的地方欢迎留言指出,您的关注是我前进的动力!