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' 对它们的引用)。
我写了一个基础 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' 对它们的引用)。