Java:错误定义的finalize方法来创建内存泄漏

时间:2013-01-24 11:09:04

标签: java

在java中,如果没有强引用指向x并且x有资格进行垃圾回收,则垃圾收集将在对象x上调用finalize方法。如果finalize方法永远不会终止,这会导致内存泄漏吗?

public class X{
  protected void finalize(){
     while(true){}
  }
}

4 个答案:

答案 0 :(得分:6)

是的,很容易测试

public class X {

    protected void finalize() {
        while (true) {
        }
    }

    public static void main(String[] args) throws Exception {
        while (true) {
            new X();
        }
    }
}

过了一段时间后

Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "main"

当我删除finalize()时,测试从未停止过。请注意,在JVM进入OOM之前需要一段时间

BTW 它足以运行此测试

public class X {
    byte[] a = new byte[100 * 1000 * 1000];

    protected void finalize() {
        System.out.println();
    }

    public static void main(String[] args) throws Exception {
        while (true) {
            new X();
        }
    }
}

打破GC

Exception in thread "main" 
java.lang.OutOfMemoryError: Java heap space
    at test.X.<init>(X.java:5)
    at test.X.main(X.java:13)

注释掉//System.out.println();它不停地工作

答案 1 :(得分:2)

是。
同样在finalize方法中,如果你对调用了finalize方法的对象提供有效的引用,Java将不会垃圾收集对象,也不会再次调用finalize方法,因为它只被调用一次。

答案 2 :(得分:2)

肯定。在finalize方法返回后,内存将被释放。如果你的finalize永远不会返回,那么momory将不会被释放。

谷歌关于垃圾收集中的复活,你会得到各种实例,其中finalize方法不保证gc

答案 3 :(得分:0)

它将阻止java.lang.ref.Finalizer $ FinalizerThread (The Secret Life Of The Finalizer),实现finalize方法的所有类的实例将在java.lang.ref.Finalizer.ReferenceQueue中被阻止。您继续使用'finalize'创建新对象,那些等待执行finalize的对象将耗尽内存。如果进行堆转储,您会看到java.lang.ref.Finalizer保留了对象,请参阅下面的示例(这是一个真实的案例)。 enter image description here