java中的finalize方法,java中finalized的用法

  java中的finalize方法,java中finalized的用法

  

finalize()方法机制

Java语言提供了对象终结机制,允许开发人员在对象被销毁之前提供自定义的处理逻辑。

 

  当GC回收垃圾时,它总是在回收之前调用这个对象的finalize()方法,一个对象的finalize()方法只会被调用一次。

  finalize()方法可以重写。通常这种方法会释放和清理一些资源,比如关闭文件、套接字和数据库连接。

  一般我们最好不要主动调用对象的finalize()方法,原因有以下三点:

  1.finalize()时,可能会导致对象复活。

  2.finalize()方法的执行时间没有保证。它完全由GC线程决定。在极端情况下,如果GC没有发生,finalize()方法将没有执行机会。

  3.一个不好的finalize()会严重影响GC的性能。例如,finalize是一个无限循环。

  为什么会有这样的机制?

  我们先来了解一下jvm为对象定义的三种状态。

  第一次被jvm标记为垃圾的对象现在处于‘试用期’阶段,也就是说这个时候不用死。

  Touchable:这个对象可以从根节点到达。

  复活:对象的所有引用都被释放,但是对象有可能在finalize()中被复活。

  不可接触:如果调用了一个对象的finalize(),并且没有复活,它将进入不可接触状态。无法恢复不可触及的对象,因为finalize()只会被调用一次。

  在上述三种状态中,不同之处在于finalize()方法的存在。只有当对象不可触摸时,它才能被回收。

  可触,即对象此时有一个引用链,是活的,复活的。意味着虽然这个对象已经被GC标记为垃圾,但是这个对象此时有可能在finalize()中复活。不可触及,也就是finalize()方法此时已经被调用(没有复活),这个对象的最终命运已经不死。

  那么具体流程是怎样的呢?

  为了确定物件objA是否可以回收,它必须经过至少两个标记过程:

  1.如果对象objA到GC根没有引用链,第一次标记它们。

  2.筛选器来确定此对象是否有必要执行finalize()方法。

  如果对象objA没有覆盖finalize()方法,或者finalize()方法已经被虚拟机调用,则认为虚拟机“不需要执行”,objA判断为不可接触。

  如果对象objA重写了finalize()方法,并且它还没有被执行,那么objA将被插入到F-Queue队列中,它的finalize()方法将被虚拟机自动创建的低优先级终结器线程触发。finalize()方法是对象逃脱死亡的最后机会。稍后,GC将第二次标记F队列队列中的对象。如果objA在finalize()方法中与引用链中的任何对象建立了连接,那么在第二次标记时,objA将被移出“即将被回收”集合。之后,将不会再有对该对象的引用。在这种情况下,finalize()方法将不会被再次调用,对象将直接变为不可触摸,即一个对象的finalize()方法只会被调用一次。

  然后我们用代码来演示对象的复活。

  公共类CanReliveObj {公共静态CanReliveObj obj//类变量,属于GC根//这个方法只能调用一次@ override protected void finalize()抛出Throwable { super . finalize();System.out.println(调用由当前类重写的finalize()方法);obj=this//当前要回收的对象与finalize()方法中引用链上的一个对象obj相连} public static void main(string[]args){ try { obj=newcanreliveobj();//对象第一次成功保存自身obj=nullsystem . GC();//调用垃圾收集器system . out . println( 1st GC );//因为终结器线程的优先级很低,暂停2秒等待它thread . sleep(2000);if(obj==null){ system . out . println( obj已死);} else {System.out.println(obj还活着);} system . out . println( 2nd GC );//下面的代码和上面的一模一样,但是这个自助失败了。obj=nullsystem . GC();//因为终结器线程的优先级很低,暂停2秒等待它thread . sleep(2000);if(obj==null){ system . out . println( obj已死);} else {System.out.println(obj还活着);} } catch(interrupted exception e){ e . printstacktrace();}}执行结果:

  先将引用指向null,然后在GC中第一次重写了finalize()方法,使得对象在第一次垃圾回收中成功保存自己,然后再次将引用指向null,因为finalize()方法只会执行一次,然后对象就只能等死了。

  这就是这篇关于Java详细介绍对象终止方法finalize()用法的文章。有关Java finalize()的更多信息,请搜索热门IT的往期文章或继续浏览下面的相关文章。我希望你以后能更多地支持流行音乐!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: