在java虚拟机的垃圾回收机制中:如果一个对象在可达性分析算法中被判定为不可达,那么垃圾回收器将会回收这个对象的内存。但在回收之前会执行一次对象的finalize()方法,如果在这个方法中对象被新的变量引用,那么垃圾回收器会放过这个对象
对象逃逸的演示过程:
class Solution {
static Solution t=null;
public static void main(String[] args) {
//new 出一个对象
t= new Solution();
//,让t指向null,此时GC Roots的引用链中没有我们new出的对象,换句话说这个对象可以被回收了
t=null;
//启动垃圾回收器
System.gc();
//我们等待500毫秒,让jvm执行垃圾回收算法
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(t==null){
System.out.println("我被回收了");
}else{
System.out.println("我还活着");
}
t=null;
//启动垃圾回收器
System.gc();
//我们等待500毫秒,让jvm执行垃圾回收算法
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(t==null){
System.out.println("我被回收了");
}else{
System.out.println("我还活着");
}
}
@Override
public void finalize()throws Throwable{
super.finalize();
System.out.println("我在执行finalize()方法,能不能逃逸就看你了!");
t=this;
}
}
控制台输出:
我们发现,我们执行了两次垃圾回收,执行结果却是一次成功逃逸,一次被回收。这是因为任何一个对象的finalize()方法都只会被系统调用一次,因此在执行第二次垃圾回收时,GCRoots引用链中没有这个对象,并且这个对象的finalize()方法已经被执行过了,因此垃圾回收器回收了这个对象的内存!