何时以及如何在Java中对类进行垃圾回收?
2022-09-01 12:03:04
当没有任何东西引用 Java 中的类时,可以对其进行垃圾回收。在大多数简单的设置中,这永远不会发生,但在某些情况下可能会发生这种情况。
有许多方法可以使课程可访问,从而阻止其有资格获得GC:
Class
ClassLoader
ClassLoader
如果这些都不成立,则它加载的类和所有类都有资格获得 GC。ClassLoader
下面是一个构造的示例(充满了不良做法!),应该可以证明这种行为:
在目录中创建字节码文件(不是包! 。它的源代码是:GCTester.class
x
public class GCTester {
public static final GCTester INSTANCE=new GCTester();
private GCTester() {
System.out.println(this + " created");
}
public void finalize() {
System.out.println(this + " finalized");
}
}
然后在的父目录中创建一个类:TestMe
x
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.lang.reflect.Field;
public class TestMe {
public static void main(String[] args) throws Exception {
System.out.println("in main");
testGetObject();
System.out.println("Second gc() call (in main)");
System.gc();
Thread.sleep(1000);
System.out.println("End of main");
}
public static void testGetObject() throws Exception {
System.out.println("Creating ClassLoader");
ClassLoader cl = new URLClassLoader(new URL[] {new File("./x").toURI().toURL()});
System.out.println("Loading Class");
Class<?> clazz = cl.loadClass("GCTester");
System.out.println("Getting static field");
Field field = clazz.getField("INSTANCE");
System.out.println("Reading static value");
Object object = field.get(null);
System.out.println("Got value: " + object);
System.out.println("First gc() call");
System.gc();
Thread.sleep(1000);
}
}
运行将产生以下(或类似)输出:TestMe
in main Creating ClassLoader Loading Class Getting static field Reading static value GCTester@1feed786 created Got value: GCTester@1feed786 First gc() call Second gc() call (in main) GCTester@1feed786 finalized End of main
在倒数第二行中,我们看到实例已最终确定,这只能表示类(和 )符合垃圾回收的条件。GCTester
ClassLoader