POJO 中的静态变量和对象的垃圾回收 类

Static variables in POJO and garbage collection of objects and classes

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

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 class

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

类似地,其他 classes 也在扩展和覆盖 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?

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

正在复制答案: “加载 class 时,无法选择静态变量进行垃圾回收。当相应的 class 加载程序(负责加载此 class)本身被垃圾回收时,它们可以被收集.

查看 JLS Section 12.7 Unloading of Classes and Interfaces

A class or interface may be unloaded if and only if its defining class loader may be reclaimed by the garbage collector [...] Classes and interfaces loaded by the bootstrap loader may not be unloaded. "

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

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

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

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

但是,分配给每个 实例 的所有内存都可以安全回收,而不会对 class对象。

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