Java 如果垃圾收集器在同一代码中保留内存两次,finalize()方法能否调用两次?
我在很多地方发现,当垃圾收集器或System.gc()成功地保留了冗余对象所消耗的内存而不再引用它时,java中的finalize()方法被调用。还发现此方法调用不超过一次。我对java并不陌生,但也不是很有经验。我可能有一个错误的理解,但让我们说一段代码Java 如果垃圾收集器在同一代码中保留内存两次,finalize()方法能否调用两次?,java,garbage-collection,Java,Garbage Collection,我在很多地方发现,当垃圾收集器或System.gc()成功地保留了冗余对象所消耗的内存而不再引用它时,java中的finalize()方法被调用。还发现此方法调用不超过一次。我对java并不陌生,但也不是很有经验。我可能有一个错误的理解,但让我们说一段代码 public class Solution { @Override protected void finalize(){ System.out.print("method called"); }
public class Solution {
@Override
protected void finalize(){
System.out.print("method called");
}
public static void main(String... args){
Solution obj1= new Solution();
Solution obj2 = new Solution();
Solution obj3 = new Solution();
System.gc();
obj1=obj2;
System.gc();
obj3=null;
System.gc();
}
}
这里,finalize方法被调用两次,因为内存堆有资格进行两次垃圾清理。因此,我有点困惑,我是否知道整个事情是正确的,或者它是否应该按照它的行为方式进行。否。finalize()
方法只会被GC在对象上调用一次。JVM在对象头中设置了一个标志(我认为),表示它已经完成,不会再完成
缔约国明确表示:
“对于任何给定对象,Java虚拟机不会多次调用finalize方法。”
当然,没有什么可以阻止对象方法多次调用this.finalize()
请注意,
finalize()
在Java 9及更高版本中由于javadoc中说明的原因而被弃用。建议您改为使用以下选项之一:
+尝试使用资源AutoCloseable
- 清洁剂
PhantomReference
有人这样说: 为收集的每个
对象调用finalize()
这是不正确的,原因如下
javadoc明确声明不保证将调用finalize
。可以保证的是,在对象的存储被回收之前,它将被调用(一次)。这是一个比评论中的陈述更弱的陈述
垃圾收集对象可能无法最终确定的一种情况是JVM在GC运行后很快退出
当类finalize
方法包含无限循环时,会出现另一种(病理性)情况。当该类的实例被终结时,终结器线程将被卡住。当所有终结器线程都以这种方式卡住时,将不再终结更多的可终结对象。他们将永远坐在终结队列中,泄漏内存
如果类中未重写对象::finalize
,JVM将跳过该类的终结步骤
它被调用了两次,因为两个不同的实例正在被GCdOr调用。我是否误解了这个问题?finalize()
是为每个收集的对象调用的。好吧,所以它不会被调用一次,而不管收集的对象的数量如何?每当从内存堆中作为垃圾收集一个不同的对象时,它就会被一次又一次地调用?另一种情况是:创建一些对象,这些对象的finalize()
方法包含一个无限循环,并让它们被收集。一旦所有终结器线程都处于忙碌状态,就不会调用其他收集对象的finalize()方法。