POJO中的静态变量以及对象和类的垃圾收集

时间:2015-04-24 08:45:53

标签: java garbage-collection static-members

我编写了一个基类来向存储库发出请求。它有一个静态字段,在应用程序中用于某些目的。

public abstract class RepositoryRequest {
    private static String version;

    {
        version = 2.0; //Actual read is happening from some configuration file.
    }

    protected String getVersion() {
        return version;
    }
}

我们有多个请求POJO,它们扩展了这个抽象类

public class ARepositoryRequest extends RepositoryRequest {
    //Some properties here
    @Override
    public String toString() {
        return "Some string generated by some logic" + getVersion();
    }
}

类似地,其他类也在扩展和覆盖toString()方法。

我对这些POJO对象的垃圾收集有一些疑问:

1. Would this kind of usage of static variable will not let the POJO objects garbage collected?
2. Is there any issue with Objects/Classes in their garbage collection?

2 个答案:

答案 0 :(得分:1)

问题已在此处回答: Are static fields open for garbage collection?

复制答案: "加载类时,无法为垃圾收集选择静态变量。当相应的类加载器(负责加载此类)本身被收集用于垃圾时,可以收集它们。

查看JLS Section 12.7 Unloading of Classes and Interfaces

  

当且仅当其定义类时,才可以卸载类或接口   垃圾收集器可以回收加载程序[...]类和   由引导加载程序加载的接口可能无法卸载。   "

答案 1 :(得分:1)

不,静态字段不会阻止子类的垃圾收集(如果确实如此,这将是一个主要问题,使得静态字段在垃圾收集语言中几乎无法使用!)

您可以通过在类中添加finalizer来测试它,然后在循环中创建一堆它们,调用System.gc()来激发垃圾收集。 如果您的finalize()方法打印出一条消息,则可以看到GC正在发生。

protected void finalize() throws Throwable {
    System.out.println("Finalize!");
}

原因是静态字段属于类对象(RepositoryRequest)。这个类在其任何实例存在时都不能被垃圾收集,并且通常不会卸载类,除非它们是ClassLoader is garbage collected,这是不寻常的。

但是,可以安全地回收分配给每个实例的所有内存,而不会对对象产生任何影响。

的情况,其中静态成员可以阻止其他数据的GC;例如,如果您将普通Collection中的类的所有实例作为静态字段进行缓存,那么它们就不能成为GCd(因为它们仍然存在'直接引用它们)。 / p>