Java #对象的finalization机制
对象的finalization机制
当对象将被垃圾回收器回收时,在回收之前,先执行对象的 finalization()方法。所以一般不主动调用finalization()方法。如果该对象没有机会被回收,finalization()方法一般没有机会执行。
finalization()是Object类的方法,可以被子类重写。
finalization()方法的执行原理:
1、当obj对象到GC Roots没有引用链时,被标记一次。
2、判断是否执行finalization()方法,如果该对象没有重写finalization()方法,或者finalization()方法已经执行过一次后,则不执行finalization()方法。
3、如果对象objA重写了finalize()方法,且还未执行过,那么objA会被插入到F-Queue队列中,由一个虚拟机自动创建的、低优先级的Finalizer线程触发其finalize()方法执行。
4、finalize()方法是对象逃脱死亡的最后机会,稍后gc会对F-Queue队列中的对象进行第二次标记。如果objA在finalize()方法中与引用链上的任何一个对象建立了联系,那么在第二次标记时,objA会被移出队列。之后,对象会再次出现没有引用存在的情况。在这个情况下,finalize方法不会被再次调用,对象会直接变成不可触及的状态,也就是说,一个对象的finalize方法只会被调用一次。
下面用代码演示该原理:
public class Main {
public static MyClass1 myClass = null;
public static void main(String[] args) {
MyClass1 myClass1 = new MyClass1();
myClass1.name="name1";
myClass1=null;
System.gc();
try {
Thread.sleep(2000);//因为Finalizer的优先级很低,所以等待2秒
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(myClass);
//第二次断开GC Root引用链
myClass=null;
System.gc();
try {
Thread.sleep(2000);//因为Finalizer的优先级很低,所以等待2秒
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(myClass);
}
}
public class MyClass1 {
public static String staticStr = "String";
public String name;
@Override
protected void finalize() throws Throwable {
System.out.println("MyClass1...finalize方法");
Main.myClass = this;
}
@Override
public String toString() {
return "MyClass1{" +
"name='" + name + '\'' +
'}';
}
}
执行结果:
MyClass1...finalize方法
MyClass1{name='name1'}
null