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


当前回答

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

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

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

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

其他回答

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

你也可以看看这篇文章:

对象终结和清理

试着运行这个程序,以便更好地理解

public class FinalizeTest 
{       
    static {
        System.out.println(Runtime.getRuntime().freeMemory());
    }

    public void run() {
        System.out.println("run");
        System.out.println(Runtime.getRuntime().freeMemory());
    }

     protected void finalize() throws Throwable { 
         System.out.println("finalize");
         while(true)
             break;          
     }

     public static void main(String[] args) {
            for (int i = 0 ; i < 500000 ; i++ ) {
                    new FinalizeTest().run();
            }
     }
}

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

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

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

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

Finalize将打印出类创建的计数。

protected void finalize() throws Throwable {
    System.out.println("Run F" );
    if ( checkedOut)
        System.out.println("Error: Checked out");
        System.out.println("Class Create Count: " + classCreate);
}

main

while ( true) {
    Book novel=new Book(true);
    //System.out.println(novel.checkedOut);
    //Runtime.getRuntime().runFinalization();
    novel.checkIn();
    new Book(true);
    //System.runFinalization();
    System.gc();

如你所见。下面的输出显示了类计数为36时第一次执行的gc。

C:\javaCode\firstClass>java TerminationCondition
Run F
Error: Checked out
Class Create Count: 36
Run F
Error: Checked out
Class Create Count: 48
Run F

An Object becomes eligible for Garbage collection or GC if its not reachable from any live threads or any static refrences in other words you can say that an object becomes eligible for garbage collection if its all references are null. Cyclic dependencies are not counted as reference so if Object A has reference of object B and object B has reference of Object A and they don't have any other live reference then both Objects A and B will be eligible for Garbage collection. Generally an object becomes eligible for garbage collection in Java on following cases:

该对象的所有引用显式设置为空,例如object = null 对象在块内创建,一旦控件退出该块,引用就会离开作用域。 父对象设置为空,如果一个对象持有另一个对象的引用,并且当您将容器对象的引用设置为空时,子对象或包含对象自动符合垃圾收集的条件。 如果一个对象只有通过WeakHashMap的活动引用,那么它就有资格进行垃圾收集。