Java:定义错误的finalize方法来创建内存泄漏
在java中,如果没有指向x的强引用并且x符合垃圾收集的条件,垃圾收集将在对象x上调用finalize方法。如果finalize方法从未终止,会导致内存泄漏吗 public class X{ protected void finalize(){ while(true){} } } 公共X类{ 受保护的void finalize(){ while(true){} } } 是的。Java:定义错误的finalize方法来创建内存泄漏,java,Java,在java中,如果没有指向x的强引用并且x符合垃圾收集的条件,垃圾收集将在对象x上调用finalize方法。如果finalize方法从未终止,会导致内存泄漏吗 public class X{ protected void finalize(){ while(true){} } } 公共X类{ 受保护的void finalize(){ while(true){} } } 是的。 同样在finalize方法内部,如果您对调用finalize方法的对象提供有效引用,Java将不会对该
同样在finalize方法内部,如果您对调用finalize方法的对象提供有效引用,Java将不会对该对象进行垃圾收集,也不会再次调用finalize方法,因为它只被调用一次 当然。Finalize方法返回后,内存将被释放。如果Finalize从未返回,momory将不会被释放
谷歌关于垃圾收集中的复活,你会得到各种各样的例子,Finalize方法不能保证gc是的,很容易测试
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运行之前需要一段时间
顺便说一句运行此测试就足够了
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)
线程“main”中出现异常
java.lang.OutOfMemoryError:java堆空间
在test.X.(X.java:5)
在test.X.main(X.java:13)
注释out//System.out.println();它可以不间断地工作它会阻止java.lang.ref.Finalizer$FinalizerThread,所有实现finalize方法的类的实例都会在java.lang.ref.Finalizer.ReferenceQueue中被阻止。如果继续使用“finalize”创建新对象,等待执行finalize的对象将耗尽内存。如果使用堆转储,您将看到java.lang.ref.Finalizer保留了对象,请参见下面的示例(这是一个真实的案例) 是什么阻止了你去尝试呢?有趣的是,在MacOSX上,程序只是在没有错误消息的情况下终止。我在while循环中添加了异常处理,但没有捕获到异常。我还添加了一些来自终结器的输出,只是为了看看它是否被调用过,但没有显示。哎呀,你永远不知道,我的回答是“是的,它可能……”Henrik顺便说一句,在它发出OOM之前需要一段时间,也许你没有等待足够长的时间?@EvgeniyDorofeev:嗯,这不是等待足够长的问题。程序只是终止了。我不是在暗示你的观察是错误的。我只是通过在我的机器上运行程序来提供我的观察结果。