我知道Java中的垃圾收集是通过释放不再可用的对象所使用的空间来自动运行的。
但为什么它会以批处理模式执行此操作?对堆对象的引用已存储在堆栈中,那么为什么不从堆栈中弹出包含这些引用的帧时释放这些对象?
答案 0 :(得分:1)
好吧,一般来说,对象的一个引用(在方法中使用)被破坏的事实不足以说明对象不再可以通过任何其他路径到达(例如方法可以共享通过将它分配给任何对象的字段来引用该引用,从而使得从堆引用的创建对象也是如此。请考虑以下示例:
public class GarbageCollectionReferenceShareDemo {
private Object objectReference;
public void runDemo() {
final Object methodReference = new Object();
objectReference = methodReference;
}
}
在上面的示例中,对正在创建的对象的引用也会发布到类的字段中。完成runDemo
方法的执行后,将销毁methodReference
引用变量(弹出堆栈帧时)。但是,必须认识到只会破坏引用而不会破坏创建的对象(存储在堆中)。 JVM运行时无法清除已创建的对象,因为它必须分析它是否可访问,并且从上面的示例判断它是否需要扫描引用方法。
长话短说:为了确定对象是否可达,垃圾收集器必须扫描从GC根开始的所有路径,主要包括所有线程的堆栈和全局变量,例如静态字段。只有这种方法允许处理通过赋值从方法中共享引用的情况。
然而,垃圾收集主题是一个非常广泛的主题,因此如果您对垃圾收集的细节感兴趣,那么我强烈建议您阅读以下书籍,该书将介绍相当多的GC细节:
The Garbage Collection Handbook: The Art of Automatic Memory Management