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



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

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?

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

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

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

原因是静态字段属于类对象(RepositoryRequest)。当该类的任何实例存在时,都不能对其进行垃圾收集,并且通常无论如何都不会卸载类,除非它们的ClassLoader是垃圾收集的,这是不寻常的。

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

的情况下,静态成员可以阻止其他数据的GC;例如,如果将普通Collection中类的所有实例缓存为静态字段,则它们不可能是GCd(因为仍然有对它们的"活动"引用)。

此处已回答问题:静态字段是否为垃圾收集打开?

正在复制答案:"在加载类时,不能选择静态变量进行垃圾收集。当相应的类加载程序(负责加载该类)本身进行垃圾收集时,可以收集静态变量。

查看JLS第12.7节卸载类和接口

类或接口可以被卸载,当且仅当其定义类加载器可以由垃圾收集器回收[…]类和由引导加载程序加载的接口可以不被卸载。">

最新更新