在java中,如果没有强引用指向x并且x有资格进行垃圾回收,则垃圾收集将在对象x上调用finalize方法。如果finalize方法永远不会终止,这会导致内存泄漏吗?
public class X{ protected void finalize(){ while(true){} } }
答案 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保留了对象,请参阅下面的示例(这是一个真实的案例)。