为什么在Java中根本无法保证执行finalize()
?是不应该使用finalize()
方法???
考虑以下计划。
class Test{
protected void finalize()
{
System.out.println("Will i execute?");
}
public static void main(String args[])
{
Test t=new Test();
}
}
此程序运行时输出为空。我们知道finalize()
用于在对象符合垃圾收集条件之前清除任何外部资源。 JVM将调用finalize()
。在finalize()
内,我们将指定在销毁对象之前必须执行的操作。 finalize()
方法是邪恶的吗?
答案 0 :(得分:3)
Javadoc link,因为会有很多引用。
我们知道finalize()用于在对象符合垃圾回收资格之前清除所有外部资源
没有。一旦对象符合垃圾收集条件,就可以调用finalize()
。理论上finalize
可以使对象不再符合垃圾收集条件,然后垃圾收集器会跳过它。如上所述
为对象调用finalize方法后,不再进一步 在Java虚拟机再次确定之前执行操作 没有任何方法可以访问此对象 任何尚未死亡的线程
为什么在Java中根本不保证执行finalize()?
保证运行。正如Javadoc所述
finalize的一般合同是,如果和何时调用它 Java™虚拟机已经确定不再有任何手段 任何尚未使用的线程都可以访问此对象 死亡,除非由于最终确定采取的行动 其他一些准备完成的对象或类。
什么不保证是何时或是否会发生垃圾收集。
我应该在java中使用finalize()吗?
这取决于您的使用案例。首先阅读javadoc并了解其含义。
答案 1 :(得分:2)
finalize()
是由对象上的垃圾收集器调用。。
您可以使用System.gc()
显式调用垃圾回收并检查您的语句是否被打印。
但是JVM可以忽略您的请求(实际上取决于JVM的实现......)。只有当JVM的内部状态告诉它有太多垃圾并且需要收集时,它才会运行GC(并且将执行行)将被打印。
答案 2 :(得分:1)
如果我理解了您的问题,您可以使用System.gc()
来请求垃圾收集,
@Override
protected void finalize() {
System.out.println("I will execute.");
}
public static void main(String args[]) {
Test t = new Test();
t = null; // <-- make it eligible for gc.
System.gc(); // <-- request gc.
System.runFinalization(); // <-- run finalization(s).
System.out.println("Exit"); // <-- exit.
}
如果您注释掉System.runFinalization();
-
public static void main(String args[]) {
Test t = new Test();
t = null; // <-- make it eligible for gc.
System.gc(); // <-- request gc.
// System.runFinalization(); // <-- run finalization(s).
System.out.println("Exit"); // <-- exit.
}
答案 3 :(得分:0)
从内存中删除对象之前垃圾收集线程调用该对象的finalize()方法,并提供执行任何类型清理操作的机会。
通常,在以下情况下,对象有资格在Java中进行垃圾收集:
如果一个对象只有WeakHashMap的实时引用,它就有资格进行垃圾回收。
public Test(){
System.out.println("Object created");
}
protected void finalize(){
System.out.println("Will i execute?");
}
public static void main(String args[]){
Test test = new Test();
test = null;
new Test();
System.gc();
}
答案 4 :(得分:0)
finalize()。
现在接下来的问题是当一个类的对象被收集为垃圾? 答案是:
当没有更多对象引用该对象时,或者根本没有对象引用指向该分配的内存空间或者对象只有通过WeakHashMap进行实时引用时,它将有资格进行垃圾回收。 Read more here
作为一个选项,我们可以使用System.gc()或Runtime.gc()来请求jvm来考虑垃圾收集。但是jvm是否会听取或忽略您的请求,这取决于以下因素: