垃圾收集器不工作?

时间:2014-04-01 07:25:33

标签: java garbage-collection

我的JDK版本是1.7.0_25

class A { 
    public void finalize() {
        System.out.println("deleting...");
    }
}

public class Test {
    public static void main(String[] args) {
        new A();
        System.gc();
        System.out.println("main class");
    }
}

我预计输出为

deleting...
main class

但在我的情况下没有输出是什么原因?当我使用JDK 1.7.0_09在线编译和运行代码时,输​​出为,

main class
deleting...

为什么“主要类”首先打印?

4 个答案:

答案 0 :(得分:1)

GC从不保证何时进行清理,

finalize() 

可能会或可能不会被召唤。

通过doin System.gc();,您只是要求调用GC,而是由JVM来完成您的请求。

Will the System.gc() invoke the cleanup?

答案取决于很多因素,例如您正在运行的JVM,它所处的模式以及它使用的垃圾收集算法。

我不会在你的代码中依赖它。如果JVM即将抛出OutOfMemoryError,则调用System.gc()不会停止它,因为垃圾收集器会在它进入极端之前尝试尽可能多地释放它。

所以...如果有什么想要肯定执行的,请不要在finalize()

中编写该代码

答案 1 :(得分:1)

最终确定时未指定。指定/保证的 only 事物是在从堆中实际删除可终结对象之前完成最终化。

实际上,终结通常由特殊的终结线程完成,该线程在主GC线程完成其工作时得到通知。看起来控件在终结线程处理对象之前返回主线程。

基本上,你不能依赖这些事情发生的顺序。这就是为什么依靠最终确定来做事情的原因之一通常是一个坏主意。

此外,甚至不能保证System.gc()电话会做任何事情。


简而言之,您所观察到的是“在最终确定的指定行为的”范围内“。垃圾收集器正在工作。这是你的期望不正确。

答案 2 :(得分:1)

当您调用System.gc()方法时,无法保证是否会调用finalize()方法。去throgh java API。对于第二个问题,main()方法是一个线程。当你调用垃圾收集器时,它将在另一个线程中执行。所以如果你理解了线程,那么现在你就会知道答案(你无法预测线程执行顺序)

答案 3 :(得分:1)

其他答案正确地说明没有办法确保终结器运行。我只想提出一些关于执行顺序的问题:

当GC检测到具有finalize()的对象 - 要删除的方法时,它不会立即删除它,而是首先将其放在终结队列中。在GC完成并且应用程序恢复工作之后,VM将开始运行所有排队的终结器 - 这应该解释输出的顺序。只有在那之后才能实际对象进行GC。