• Java魔法堂:finalize函数


    一、finalize与GC                            

      在GC第一次进行可达性分析时会将不可达而且该对象所属类重写finalize方法finalize方法重未被执行过的对象追加到F-Queue当中,然后JVM会自动开启一个低优先级的守护线程Finalizer执行F-Queue中元素的finalize方法。此时可通过finalize方法重新将不可达对象与引用链关联起来,那么在GC第二次进行可达性分析时,则可逃离被回收的名单。

    class FinalizeEscapeGC{
      public static FinalizeEscapeGC SAVE_HOOK = null;
      public void isAlive(){
         System.out.println("yes, i am still alive;");
      }
    
      @override
      protected void finalize() throws Throwable{
        super.finalize();
        System.out.println("finalize method executed!");
        FinalizeEscapeGC.SAVE_HOOK = this;
      }
    
      public static void main(String[] args) throws Throwable{
          SAVE_HOOK = new FinalizeEscapeGC();
    
          SAVE_HOOK = null;
          System.gc();
          Thread.sleep(500);
          if (SAVE_HOOK == null) SAVE_HOOK.isAlive();
          else System.out.println("no, i am dead :(");
                
          SAVE_HOOK = null;
          System.gc();
          Thread.sleep(500);
          if (SAVE_HOOK == null) SAVE_HOOK.isAlive();
          else System.out.println("no, i am dead :(");
      }
    }

    第一次成功通过finalize方法成功逃脱回收名单,但第二次因为finalize方法之前已经被调用过,因此不会在执行finalize方法,所以注定被回收了。

    注意:finalizer线程执行每个对象的finalize方法时是非阻塞的,因此并不保证GC进行第二次标记时finalize方法执行完成。

    二、在finalize方法中释放资源?                   

      说起finalize方法大家就会联想到析构函数,并希望像析构函数那样使用,然后什么资源释放收尾等工作都放在finalize方法中。其实这只是让C/C++程序员更容易转向Java阵营的妥协而已,大家最好还是忘记有这一个方法吧,通过try-catch-finally释放资源更有效。

      尊重原创,转载请注明来自:http://www.cnblogs.com/fsjohnhuang/p/4269086.html  ^_^肥仔John

  • 相关阅读:
    [工具分享]JetBrains ReSharper 9.0 正式版和注册码
    JAVA数据库连接池的革命 -- 从BoneCP到HikariCP
    【C#教程10】C# 判断
    【C#教程09】C# 运算符
    【C#教程07】C# 变量
    【C#教程06】C# 类型转换
    【C# 教程05】C# 数据类型
    【C# 教程04】C# 基本语法
    【C# 教程03】C# 程序结构
    【C#教程02】C# 环境
  • 原文地址:https://www.cnblogs.com/fsjohnhuang/p/4269086.html
Copyright © 2020-2023  润新知