我编写了一个基类来向存储库发出请求。它有一个静态字段,在应用程序中用于某些目的。
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?
答案 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>