image

编辑人: 未来可期

calendar2025-01-23

message1

visits895

说说你理解的finalize

分析&回答

  • 调用GC并不保证GC实际执行
  • finalize抛出的未捕获异常只会导致该对象的finalize执行退出。
  • 用户可以自己调用对象的finalize方法,但是这种调用是正常的方法调用,和对象的销毁过程无关。
  • JVM保证在一个对象所占用的内存被回收之前,如果它实现了finalize方法,则该方法一定会被调用。Object的默认finalize什么都不做,为了效率,GC可以认为一个什么都不做的finalize不存在。
  • 对象的finalize调用链和clone调用链一样,必须手工构造。
protected void finalize() throws Throwable { 
    super.finalize(); 
}

finalize使用注意点

  1. 尽量不要用finalize,太复杂了,还是让系统照管比较好。可以定义其它的方法来释放非内存资源。
  2. 如果用,尽量简单。
  3. 如果用,避免对象再生,这个是自己给自己找麻烦。
  4. 可以用来保护非内存资源被释放。即使我们定义了其它的方法来释放非内存资源,但是其它人未必会调用该方法来释放。在finalize里面可以检查一下,如果没有释放就释放好了,晚释放总比不释放好。
  5. 即使对象的finalize已经运行了,不能保证该对象被销毁。要实现一些保证对象彻底被销毁时的动作,只能依赖于java.lang.ref里面的类和GC交互了。

反思&扩展

finalize VS System.gc

  • finalize方法在垃圾回收器准备垃圾回收前被调用,但是不一定会被调用
  • finalize()其实是用来释放不是通过java的new关键字分配的内存比如说通过本地方法调用了c程序,该c程序malloc分配了内存,那么垃圾回收器就不能通过java语言来释放内存,只能在finalize方法内通过本地方法调用c程序进行释放内存
  • System.gc()建议垃圾回收器进行垃圾回收,但是不一会立即执行,不管新的对象还是旧的对象都会进行回收,是full gc

对象再生

任何时候,GC都可以从F-Queue中拿到一个Finalizable的对象,标记它为Finalized,然后执行它的finalize方法,由于该对象在这个线程中又可达了,于是该对象变成Reachable了(并且Finalized)。而finalize方法执行时,又有可能把其它的F-Reachable的对象变为一个Reachable的,这个叫做对象再生


喵呜面试助手: 一站式解决面试问题,你可以搜索微信小程序 [喵呜面试助手] 或关注 [喵呜刷题] -> 面试助手 免费刷题。如有好的面试知识或技巧期待您的共享!

创作类型:
原创

本文链接:说说你理解的finalize

版权声明:本站点所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明文章出处。
分享文章
share