1

我试图查看垃圾收集器何时“垃圾收集”一个对象。根据文档,当垃圾收集器“删除”一个对象时,会调用一次 finalize() 方法。

我试图覆盖 finalise() 以查看在我使对象无效后是否可以看到它在什么时候被调用,但我似乎在无限期地等待。这应该工作吗?

class Dog{
    ZiggyTest2 z;
    public Dog(ZiggyTest2 z){
        this.z = z;
    }

    protected void finalize() throws Throwable {
        try {
            synchronized(z){
                System.out.println("Garbage collected");
                z.notify();
            }
        } finally {
            super.finalize();
        }
    }
}

主要课程:

class ZiggyTest2{

    public static void main(String[] args){

    ZiggyTest2 z = new ZiggyTest2();        
    Dog dog = new Dog(z);   

        synchronized(z){
            try{
                dog = null;
                z.wait();
            }catch(InterruptedException ie){
                System.out.println("Interrupted");
            }           
        }
    }   
}

我想做的是在我使 Dog 对象无效后看到 finalise() 方法被调用。这就是为什么我将 notify() 语句放在 finalize() 方法中。它不起作用,它只是一直在等待..

编辑

多谢你们。在我修改 ZiggyTest2 以添加 System.gc(); 后,我让它工作了。

class ZiggyTest2{

    public static void main(String[] args){

    ZiggyTest2 z = new ZiggyTest2();        
    Dog dog = new Dog(z);   

        synchronized(z){
            try{
                dog = null;
                System.gc();
                z.wait();
            }catch(InterruptedException ie){
                System.out.println("Interrupted");
            }           
        }
    }   
}

输出:

C:\>java ZiggyTest2
Garbage collected
4

3 回答 3

2

System.gc()设置 dog = null 后尝试添加 a 。

于 2011-12-27T13:15:30.757 回答
2

垃圾收集器仅在需要时运行。如果您的程序不需要执行 GC,它可以在没有 GC 的情况下运行一整天。您可以调用 System.gc() 来尝试触发 GC。

注意:如果你有一个 finalize 方法,gc 不会等待在后台线程中调用 finalize 方法,因此该对象可能存在,直到 GC AFTER finalize 被调用。

于 2011-12-27T13:15:33.010 回答
1

好吧,首先不能保证垃圾收集器何时运行以及将收集什么。收集器很可能不会在您的示例中运行,因为还有大量可用内存。您可以使用System.gc(),但不能保证这会真正触发收集器,它只是向 JVM 提示您希望它运行垃圾收集器。

此外,finalize()每个实例只会运行一次,即当finalize()阻止收集对象时,任何进一步的垃圾收集运行都不会finalize()再次调用,但它可能会收集对象。

于 2011-12-27T13:18:30.337 回答