0
点赞
收藏
分享

微信扫一扫

JVM_哪些对象可以作为GC Roots

骑在牛背上看书 2023-05-18 阅读 110

GC Roots 对象包括以下几种:(巧记:两栈两方法)

  • 虚拟机栈中引用的对象
  • 方法区中类静态属性引用的对象
  • 方法区中常量引用的对象
  • 本地方法栈中 JNI 引用的对象

虚拟机栈中引用的对象

虚拟机栈中引用的对象是指在 Java 程序中,方法中的局部变量所引用的对象。当一个方法被调用时,虚拟机会为该方法创建一个栈帧,栈帧中包含了该方法的局部变量表,其中存储了该方法中定义的所有局部变量及其引用的对象。

举个例子,假设有如下的 Java 代码:

public class Example {
    public static void main(String[] args) {
        int a = 1;
        String b = "hello";
        Object c = new Object();
        // ...
    }
}

在这个例子中,main 方法中定义了三个局部变量 abc,其中 a 是一个基本数据类型,不是一个对象,因此不会被视为虚拟机栈中引用的对象。而 b 是一个 String 类型的对象,c 是一个 Object 类型的对象,它们都是虚拟机栈中引用的对象。

main 方法执行完毕后,虚拟机会将该方法的栈帧出栈,同时也会将其中的局部变量表中引用的对象释放掉,以便垃圾回收器回收这些对象所占用的内存空间。

本地方法栈中 JNI 引用的对象

本地方法栈中 JNI 引用的对象是指在 Java 程序中,使用 JNI(Java Native Interface)调用本地方法时所引用的对象。JNI 是一种机制,它允许 Java 程序调用本地方法,即使用 C 或 C++ 等语言编写的方法。

举个例子,假设如下的 Java 代码:

public class Example {
    public static native void nativeMethod(Object obj);
    // ...
}

在这个例子中,Example 类中定义了一个本地方法 nativeMethod,它接受一个 Object 类型的参数。在本地方法中,可以使用 JNI 调用 C 或 C++ 等语言编写的方法,同时也可以将 Java 对象作为参数传递给本地方法。

当程序运行时,如果调用了 Example 类的 nativeMethod 方法,并将一个 Java 对象作为参数传递给该方法,那么这个 Java 对象就会被视为本地方法栈中 JNI 引用的对象。

当本地方法执行完毕后,虚拟机会将本地方法栈出栈,同时也会将其中引用的对象释放掉,以便垃圾回收器回收这些对象所占用的内存空间。

方法区中类静态属性引用的对象

方法区中类静态属性引用的对象是指在 Java 程序中,类的静态属性所引用的对象。静态属性是指在类中使用 static 关键字修饰的属性,它属于类本身而不是类的实例,因此在程序运行期间只会被创建一次。

举个例子,假设如下的 Java 代码:

public class Example {
    private static String message = "hello";
    // ...
}

在这个例子中,Example 类中定义了一个静态属性 message,它是一个 String 类型的对象,因此它是方法区中类静态属性引用的对象。

当程序运行时,虚拟机会为 Example 类创建一个类对象,并将其中的静态属性 message 初始化为 "hello"。在程序运行期间,如果其他代码中引用了 Example 类的静态属性 message,那么这个静态属性所引用的对象就会被视为方法区中类静态属性引用的对象。

当程序结束时,虚拟机会将 Example 类的类对象和其中的静态属性释放掉,以便垃圾回收器回收这些对象所占用的内存空间。

方法区中常量引用的对象

方法区中常量引用的对象是指在 Java 程序中,使用 final 关键字定义的常量所引用的对象。常量是指在程序运行期间不可变的值,一旦被初始化后就不能再被修改。

举个例子,假设如下的 Java 代码:

public class Example {
    private static final String MESSAGE = "hello";
    // ...
}

在这个例子中,Example 类中定义了一个常量 MESSAGE,它是一个 String 类型的对象,因此它是方法区中常量引用的对象。

当程序运行时,虚拟机会为 Example 类创建一个类对象,并将其中的常量 MESSAGE 初始化为 "hello"。在程序运行期间,如果其他代码中引用了 Example 类的常量 MESSAGE,那么这个常量所引用的对象就会被视为方法区中常量引用的对象。

当程序结束时,虚拟机会将 Example 类的类对象和其中的常量释放掉,以便垃圾回收器回收这些对象所占用的内存空间。由于常量是不可变的,因此它们所引用的对象也不会被修改,因此在程序运行期间它们所引用的对象一直都是相同的。

举报

相关推荐

0 条评论