Java 垃圾收集器不工作?

Java 垃圾收集器不工作?,java,garbage-collection,Java,Garbage Collection,我的JDK版本是1.7.025 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"

我的JDK版本是1.7.025

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
但在我的情况下,没有输出是什么原因?当我用JDK1.7.0_09在线编译和运行代码时,输出是

main class
deleting...

为什么“主类”先打印?

GC从不保证何时进行清理

finalize() 
可以叫也可以不叫

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

System.gc()会调用清理吗?

答案取决于很多因素,比如运行在哪个JVM上,处于哪个模式,以及使用哪个垃圾收集算法

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


所以。。。如果您确实想执行任何操作,请不要将该代码写入
finalize()

GC无法保证何时进行清理

finalize() 
可以叫也可以不叫

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

System.gc()会调用清理吗?

答案取决于很多因素,比如运行在哪个JVM上,处于哪个模式,以及使用哪个垃圾收集算法

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


所以。。。如果您确实想执行任何操作,请不要在
finalize()

中写入该代码,因为它没有指定何时完成。唯一指定/保证的是,在可终结对象实际从堆中删除之前,将发生终结

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

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

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



简言之,您所观察到的是“在封套内”完成指定行为。垃圾收集器正在工作。您的期望是不正确的。

未指定何时完成。唯一指定/保证的是,在可终结对象实际从堆中删除之前,将发生终结

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

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

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



简言之,您所观察到的是“在封套内”完成指定行为。垃圾收集器正在工作。您的期望是不正确的。

当您调用
System.gc()
方法时,无法保证finalize()方法是否会被调用。通过JavaAPI。对于第二个问题,main()方法是一个线程。当您调用垃圾收集器时,它将在另一个线程中执行。因此,如果您了解线程,现在您将知道答案(您无法预测线程执行顺序)

当您调用
System.gc()
方法时,无法保证finalize()方法是否会被调用。通过JavaAPI。对于第二个问题,main()方法是一个线程。当您调用垃圾收集器时,它将在另一个线程中执行。因此,如果您了解线程,现在您将知道答案(您无法预测线程执行顺序)

其他答案正确地指出,无法确保终结器运行。我只是想补充一些关于执行令的问题:


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

其他答案正确地指出,没有办法确保终结器运行。我只是想补充一些关于执行令的问题:


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

GC从不保证何时进行清理,finalize()可以通过doin
System.GC()调用,也可以不调用您只请求调用GC,但要由JVM来完成您的请求。GC从不保证当清理发生时,finalize()可以通过doin
System.GC()调用,也可以不调用