转载

【深入浅出-JVM】(26):对象的复活

package com.mousycoder.mycode.thinking_in_jvm;

/**
 * 对象的复活
 *
 * @version 1.0
 * @author: mousycoder
 * @date: 2019-07-06 15:32
 */
public class CanReliveObj {

    public static CanReliveObj obj;

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        System.out.println("CanReliveObj finalize called");
        obj = this;
    }

    @Override
    public String toString() {
        return "I am CanReliveObj";
    }

    public static void main(String[] args) throws InterruptedException {
        obj = new CanReliveObj();
        obj = null;
        System.gc();
        Thread.sleep(1000);
        if (obj == null) {
            System.out.println("obj 是null");
        }else {
            System.out.println("obj 可用");
        }

        System.out.println("第 2 次 gc");
        obj = null;
        System.gc();
        Thread.sleep(1000);
        if (obj == null) {
            System.out.println("obj 是 null");
        }else {
            System.out.println("obj 可用");
        }
    }


}

输出:

CanReliveObj finalize called
obj 可用
第 2 次 gc
obj 是 null

说明:

第一次 GC 的时候,finalize()方法中被复活了,对象状态变成可触及性,但是 finalize() 方法只会被调用一遍,所以第二次没办法复活 就为 null

finalize

  1. finalize() 里方法里的异常会被忽略,同时方法终止,但是并不影响主线程,只保证方法执行,不保证方法执行成功
  2. finalize() 方法只会在准备回收该对象时调用
  3. 设计原意是在回收该对象的时候,释放非 java 资源,例如:FileInputStream类
    【深入浅出-JVM】(26):对象的复活
  4. 流程: 当对象的 GC Roots 不可达,GC 会判断该对象是否覆盖了 finalize 方法,未覆盖,则回收。否则,若未执行过 finalize方法,则放入 F-Queue,由低优先级线程执行对象的 finalize方法,执行完毕后,GC 会再次判断该对象是否可达,若不可达,则回收,否则,复活
原文  http://mousycoder.com/thinking-in-jvm/26/
正文到此结束
Loading...