java进行垃圾回收的时候,我们知道都是用三色标记法配合根节点往下进行GC的,那代码里面的哪些东西会被识别为根节点呢?常见的根节点包括:
- 局部变量和参数:在方法中被声明的基本数据类型和对象引用。
- 活动线程:正在运行的线程中的所有对象都被视为根节点,因为它们正在被使用。
- 静态变量:属于类而不是对象的变量,它们被存储在类的内部中,被视为根节点。
- JNI(Java Native Interface)引用:JNI可以在Java代码和本地代码(如C或C++)之间进行交互,本地代码中的所有对象都被视为根节点。
- 虚拟机内部的一些对象:例如Class对象和常量池中的字符串等,这些对象被视为根节点,因为它们是虚拟机内部的常驻对象。
public class RootNodeExample {
public static void main(String[] args) {
// 局部变量作为根节点
String str = "Hello, world!";
// 创建对象数组
Object[] objArray = new Object[100];
// 静态变量作为根节点
RootNodeExample.staticObj = new Object();
// 创建线程并启动
Thread t = new Thread(new Runnable() {
public void run() {
// 新线程中的对象作为根节点
Object threadObj = new Object();
// ...
}
});
t.start();
// 创建JNI对象并使用
MyJNIObject jniObj = new MyJNIObject();
jniObj.doSomething();
// 等待一段时间
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 强制进行垃圾回收
System.gc();
}
// 静态变量
private static Object staticObj;
// 内部类,作为JNI对象的示例
private static class MyJNIObject {
private native void doSomething();
}
}
可能会有这样的疑惑,那如果int a = 2,那这个a会被当作根节点吗,其实基本数据类型并不是对象,因此它们并不会被视为根节点。在Java中,基本数据类型是值类型,而不是引用类型,因此它们的值是直接存储在栈内存中的。在垃圾回收时,只有那些被分配在堆上的对象才需要进行垃圾回收。