没有任何引用时,可以对Java中的类进行垃圾回收。在大多数简单的设置中,这永远不会发生,但是在某些情况下可能会发生。
有很多方法可以使类可达,从而阻止其符合GC的资格:
- 该类对象仍然可以访问。
Class
表示类的对象仍然可以访问- 在
ClassLoader
这加载的类仍可达 ClassLoader
仍然可以加载由加载的其他类
如果 没有 那些都是真的,那么
ClassLoader它加载,并且所有的类都是符合GC。
这是一个结构化的示例(充满了不良习惯!),该示例可以证明行为:
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将产生以下(或类似的)输出:
在主要创建ClassLoader装载类获取静态场读取静态值创建GCTester @ 1feed786获得值:GCTester @ 1feed786第一次gc()调用第二次gc()调用(主要)GCTester @ 1feed786最终确定主端
在倒数第二行中,我们看到
GCTester实例已完成,这仅意味着该类(和
ClassLoader)可以进行垃圾收集。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)