我需要知道什么时候在JVM中调用finalize()方法。我创建了一个测试类,当finalize()方法被重写时写入文件。它没有被执行。有人能告诉我为什么它不能执行吗?


当前回答

最终确定方法是不保证的。当对象符合GC条件时调用此方法。在许多情况下,对象可能不会被垃圾收集。

其他回答

查看Effective Java,第2版第27页。 第7项:避免终结词

终结器是不可预测的,通常是危险的,而且通常是不必要的。永远不要在终结器中做任何时间紧迫的事情。从来没有 依赖终结器更新关键持久状态。

要终止一个资源,请使用try-finally:

// try-finally块保证终止方法的执行 Foo Foo =新的Foo(…); 尝试{ //用foo做必须做的事情 ... }最后{ foo.terminate ();//显式终止方法 }

类,在其中重写finalize方法

public class TestClass {    
    public TestClass() {
        System.out.println("constructor");
    }

    public void display() {
        System.out.println("display");
    }
    @Override
    public void finalize() {
        System.out.println("destructor");
    }
}

finalize方法被调用的几率

public class TestGarbageCollection {
    public static void main(String[] args) {
        while (true) {
            TestClass s = new TestClass();
            s.display();
            System.gc();
        }
    }
}

当内存被转储对象重载时,gc将调用finalize方法

运行并查看控制台,在那里你不会发现finalize方法被频繁调用,当内存超载时,finalize方法将被调用。

JDK 18的最新消息

根据openjdk 18发布的JEPS 421, finalize()方法的终结和功能将被标记为已弃用(forRemoval=true),这意味着永久删除将在jdk 18之后的某个后续版本中进行。

从jdk 18开始,一个新的命令行选项——finalization=disabled禁用了所有地方的终结机制,甚至是jdk内部的声明。

这也与这里的这个问题有关,因为它被计划删除的原因是它包含的一些主要缺陷。其中一个缺陷是,从一个对象变得不可访问到调用它的终结器之间可能会经过很长一段时间。GC也不能保证任何终结器将被调用,这也是事实。

protected void finalize() throws Throwable {} every class inherits the finalize() method from java.lang.Object the method is called by the garbage collector when it determines no more references to the object exist the Object finalize method performs no actions but it may be overridden by any class normally it should be overridden to clean-up non-Java resources ie closing a file if overridding finalize() it is good programming practice to use a try-catch-finally statement and to always call super.finalize(). This is a safety measure to ensure you do not inadvertently miss closing a resource used by the objects calling class protected void finalize() throws Throwable { try { close(); // close open files } finally { super.finalize(); } } any exception thrown by finalize() during garbage collection halts the finalization but is otherwise ignored finalize() is never run more than once on any object

引用自:http://www.janeg.ca/scjp/gc/finalize.html

你也可以看看这篇文章:

对象终结和清理

finalize方法在对象即将被垃圾收集时被调用。这可以在它有资格进行垃圾收集之后的任何时间进行。

注意,完全有可能一个对象永远不会被垃圾收集(因此finalize永远不会被调用)。当对象永远不符合gc条件(因为在JVM的整个生命周期内都可以访问它),或者在对象符合条件到JVM停止运行之间没有实际运行垃圾收集时(这种情况经常发生在简单的测试程序中),就会发生这种情况。

有一些方法可以告诉JVM在尚未调用的对象上运行finalize,但使用这些方法也不是一个好主意(该方法的保证也不是很强)。

如果您依赖finalize来实现应用程序的正确操作,那么您就做错了一些事情。finalize只能用于清理(通常是非java)资源。这正是因为JVM不能保证finalize在任何对象上都被调用。