JVM系列(六) JVM 对象终结方法finalize

我们有几个特别容易混淆的关键字final、finally、finalize, 他们之间的区别是什么?

  • final 是java关键字
  • finally 是try-catch-finally
  • finalize 是Object 根类的方法

今天我们着重讲下 finalize方法

1.finalize方法的原理及调用

finalize方法也是Java中所有类中必有的方法,因为它是属于Object根类的方法,默认情况下,Java中所有的类都是Object类的子类。

  • 在GC准备释放对象所占用的内存空间之前,它将首先调用finalize()方法。
  • finalize()方法可以处理系统资源,执行清理活动并最大程度地减少内存泄漏。
  • 简单来说可在释放对象前进行某些操作

那么什么时候调用 finalize方法呢?

  1. 当对象被回收时,系统自动调用该对象的finalize方法,子类可以重写该方法,做一些释放资源的操作。
  2. 什么时候被回收:当某个对象没有任何引用时,jvm就认为这个对象是一个垃圾对象,就会使用垃圾回收机制来销毁该对象
  3. 在销毁对象前,会先调用finalize方法。
  4. 垃圾回收机制的调用,是由系统来决定,也可以通过System.gc()主动触发垃圾回收机制。
  5. 并不是说有一个垃圾对象,垃圾回收器立马回收,它有一套自己的算法

2.finalize方法测试

创建MyBigObject 重写 finalize方法
在对象销毁前,或者释放资源前 加入自己的操作


@Slf4j
public class MyBigObj {
    private String name;

    public MyBigObj(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }


    @Override
    public String toString() {
        return "MyBigObj{" +
                "name='" + name + ''' +
                '}';
    }

    /**
     * 子类重写此方法,可在释放对象前进行某些操作
     */
    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        System.out.println("==========加入某些操作! 释放了资源");
    }

}

然后创建测试类, 构建对象

手动执行GC, 释放系统资源, 触发垃圾回收

@Slf4j
public class FinalTest {

    public static void main(String[] args) throws Exception {

        //测试finalize
        MyBigObj obj = new MyBigObj("aaa");
        log.info("======obj:" + obj);

        //将 obj 对象置为 null, 此刻obj对象实体就是垃圾对象
        // obj 等待被回收。但是 回收的时间不确定。
        obj = null;


        //强制性释放空间
        System.gc();

        Thread.sleep(1000);
        log.info("======obj:" + obj);
    }
}

查看finalize方法执行结果

执行结果

  • 先创建对象 MyBigObj{name=‘aaa’}
  • 然后 将obj 设置为null,变为可回收对象
  • 然后执行 gc主动释放对象,触发垃圾回收
  • 然后 执行 obj.finalize方法 打印 加入某些操作! 释放了资源
  • 然后打印 obj 对象 =null
21:53:31.523 [main] INFO com.jzj.tdmybatis.util.FinalTest - ======obj:MyBigObj{name='aaa'}
==========加入某些操作! 释放了资源
21:53:32.538 [main] INFO com.jzj.tdmybatis.util.FinalTest - ======obj:null

3.finalize终结方法的应用场景

下面我们介绍一下 finalize终结方法的应用场景

  • JVM的垃圾回收会负责调用这个方法。
  • finalize 不像equals()和toString(),equals()和toString()方法是需要你写代码调用的
  • finalize()只需要重写,重写完将来自动机制来调用。
  • 当一个java对象即将被垃圾回收器回收的时候,垃圾回收器负责调用finalize()方法。
  • 象销毁时机执行一段业务逻辑,这段逻辑要写在finalize()方法当中。
  • java 中的垃圾回收器不是轻易启动的,垃圾太少,或者时间没到,种种条件下,有可能启动,也有可能不启动
  • 因此finalize方法的执行时刻也是不确定的

至此 我们讲明白了finalize终结方法的使用及调用时机,便于我们理解 jvm在回收垃圾时候的操作流程

你可能感兴趣的:(jvm,java,开发语言,finalize方法)