JVM之判断一个对象是否存活

        真正要宣告一个对象死亡,至少要经历两次标记:

        1、  如果对象在进行可达性分析后发现没有与GC Root相连接的引用链,将会被第一次标记,并且进行一次筛选,筛选条件是对象是否有必要执行finalize()方法,当对象没有覆盖finalize()方法或finalize()方法已经被虚拟机调用过,虚拟机将这两种情况称为没有必要执行。

        2、  如果对象被判定为有必要执行finalize()方法,那么该对象将会被放置到低优先级的Finalize线程去执行它,但不承若会等待它运行结束,GC将对F_Queue中的对象进行第二次小规模的标记,如果对象要在finalize()方法中成功解救自己,只要重新与引用链上的任何一个对象建立关联即可,如果对象这时候还没有逃脱那基本上它就真的被回收了。


/**
 * 此代码演示了两点: 
 *    1、对象可以被GC是自我拯救 
 *    2、这种自救的机会只有一次,因为一个对象的finalize()方法最多只会被系统调用一次
 * @author xiaomage
 * 
 */
public class FinalizeEscapeGC {
   
	private static FinalizeEscapeGC SAVE_HOOK = null;
	public void isAlive(){
		System.out.println("yes, i am still alive :)");
	}
	
	protected void finalize() throws Throwable {
		super.finalize();
		System.out.println("finalize method execute");
		FinalizeEscapeGC.SAVE_HOOK = this;
	}
	public static void main(String[] args) throws InterruptedException {
		SAVE_HOOK = new FinalizeEscapeGC();
		
		//对象第一次解救成功
		SAVE_HOOK = null;
		System.gc();
		//因为finalize()方法优先级低,所以暂停0.5秒以等待它
		Thread.sleep(500);
		if(SAVE_HOOK != null){
			SAVE_HOOK.isAlive();
		}else{
			System.out.println("no , i am dead :(");
		}
		
		//下面的代码与上面的代码完全相同,但是这次自救却失败了
		SAVE_HOOK = null;
		System.gc();
		//因为finalize()方法优先级低,所以暂停0.5秒以等待它
		Thread.sleep(500);
		if(SAVE_HOOK != null){
			SAVE_HOOK.isAlive();
		}else{
			System.out.println("no , i am dead :(");
		}


你可能感兴趣的:(Java虚拟机)