美文网首页
Finalize 与 GC

Finalize 与 GC

作者: 漠简尘 | 来源:发表于2017-04-16 15:26 被阅读0次

预备知识

  • Java的Gc只负责内存的清理,其它方面的清理要程序员手工操作
  • 调用Gc并不能保证Gc一定会执行,因为GC的线程优先级比较低,所以在测试的时候调用完GC一般使当前线程睡眠以便GC线程的执行。
  • 用户自己调用finalize函数并不会影响到清理,和调用一个正常的方法一样,没有什么特别的影响
  • jvm保证一个对象占用的内存回收之前,如果这个对象的类实现了finalize方法,一定会执行且仅执行一次,至于如何保证的会在下面讲到
  • 对象的finalize链需要手工构造,也就是如果重写finalize函数需要手动调用super.finalize()

对象的销毁过程

没有重写finalize方法

  • 刚创建的对象状态是reachable,如果对象变成不可达,GC会直接将对象销毁

重写了finalize方法

  • 刚创建:reachable + unfinalized状态,意思是:该对象可达,而且该对象的finalize函数还没有被调用,并且没有准备被调用,因为该对象可达GC不会试图去销毁该对象。
  • 对象的引用没有了,现在是不可达状态,但是因为其重写了finalize函数,所以jvm会将该对象放到F-queue中,该队列中的对象状态都变成:F-reachable + finalizable,意思是:该对象通过F-queue可达而且准备被调用finalize函数。
  • 在任何时候,如果F-queue队列非空,GC的一个线程都会从该队列中取出一个对象,将其状态标记为:unreachable + finablized,并执行它的finalize函数, 意思是:该对象现在不可达,而且已经执行过finalize函数,不能再次被放到F-queue队列中,也就保证了finalize只会被执行一次。
  • 如果F-queue中的一个对象在其finalize函数中“复活了自己”---将自己的引用又赋值给了一个变量,这个时候这个对象就再次变成了reachable,但是他的finalize函数仍然不会被再次执行,也就是说它现在的状态类似于一个没有覆盖finalize函数的对象,如果再次变得不可达,会直接被GC销毁。
  • 下面演示一个对象在finalize函数中复活自己的例子:
public class Main{
    static Main HOOK;

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

    public static void main(String[] args) throws InterruptedException {
        HOOK = new Main();
        HOOK=null;
        System.gc();
        Thread.sleep(3000);
        if(HOOK==null){
            System.out.println("object is dead");
        }else {
            System.out.println("object is alive");
        }

        HOOK=null;
        System.gc();
        Thread.sleep(3000);
        if(HOOK==null){
            System.out.println("object is dead");
        }else {
            System.out.println("object is alive");
        }
    }
}
  • output:
finalize function is called
object is alive
object is dead
  • GC第一次执行的时候,调用了finalize函数,通过将this引用赋值给另一个变量,将对象复活,所以对象仍然是存活的,但是第二次就不会在调用finalize函数,所以对象被销毁。

相关文章

  • Finalize 与 GC

    预备知识 Java的Gc只负责内存的清理,其它方面的清理要程序员手工操作 调用Gc并不能保证Gc一定会执行,因为G...

  • 2020-07-21 Finalize和Dispose

    Finalize和Dispose都是用来释放资源的。 Finalize也就是析构函数,是由gc来决定的,等到gc执...

  • finalize方法相关

    finalize原理简述 当一个对象变成(GC Roots)不可达时,GC会判断对象是否覆盖了finalize方法...

  • finalize 与 Java GC

    闲逛ITEye时看到了译帝的一篇翻译博客,其中提到了关于Java类重写finalize方法后带来的诡异的GC ov...

  • (转)Java面试重难点剖析(部分)

    1、高并发访问数据库优化方法 2、java finalize方法总结、GC执行finalize的过程 3、简单理解...

  • gc&finalize()

    gc:垃圾回收finalize():是类似于析构函数的东西,如果覆写了该方法,则在垃圾回收过程中会调用该方法,然后...

  • GC垃圾回收机制

    GC算法 垃圾收集器 (标记-清除,复制,压缩,gc垃圾收集需要判断是否覆盖finalize方法?) 概述 垃圾收...

  • java finalize方法总结、GC执行finalize的过

    注:本文的目的并不是鼓励使用finalize方法,而是大致理清其作用、问题以及GC执行finalize的过程。 1...

  • 垃圾回收机制算法分析

    什么是垃圾回收机制? JVM参数-查看GC日志 : -XX:+PrintGCDetails finalize方法作...

  • JVM Finalizer线程踩坑记录

    一、finalize方法是对象回收前的唯一自我救赎机会 JVM进行GC时,首先使用可达性分析算法,找出不在GC R...

网友评论

      本文标题:Finalize 与 GC

      本文链接:https://www.haomeiwen.com/subject/pzuaattx.html