浅析finalize方法「建议收藏」

浅析finalize方法「建议收藏」昨天有个小伙伴聊到java对象finalize方法。于是就想好好总结一下。咱们都知道判断一个对象是否已经死了的方法有两种:1:引用计数法2:可达性分析算法由于我们通常使用…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

640?wx_fmt=png

昨天有个小伙伴聊到java对象finalize方法。于是就想好好总结一下。

咱们都知道判断一个对象是否已经死了的方法有两种:

1:引用计数法

2:可达性分析算法

由于我们通常使用的虚拟机使用的可达性分析算法,所以我们这里聊的都是可达性分析算法的相关。

判断一个对象时生存还是死亡???

即使在可达性分析算法中不可导的对象,也并非就是‘非死不可’的,这时候我们可以理解为改对象暂时处于“缓刑”阶段,跟死囚犯一样,还是有机会不被砍头的。

 

说明一个对象已经死亡,至少需要经历两个被标记过程:

 

如果对象在进行可达性分析后发现没有与GC Roots相连接的引用链,那它将会被第一次标记并且进行一次筛选,筛选的条件是此对象是否有必要执行finalize()方法。当对象没有覆盖finalize()方法,或者finalize()方法已经被虚拟机调用过,虚拟机将这两种情况都视为“没有必要执行”。

 

如果这个对象被判定为有必要执行finalize()方法,那么这个对象将会放置在一个叫做

F-Queue的队列之中,并在稍后由一个由虚拟机自动建立的、低优先级的Finalizer线程去执行它。这里所谓的“执行”是指虚拟机会触发这个方法,但并不承诺会等待它运行结束,这样做的原因是,如果一个对象在finalize()方法中执行缓慢,或者发生了死循环(更极端的情况),将很可能会导致F-Queue队列中其他对象永久处于等待,甚至导致整个内存回收系统崩溃。finalize()方法是对象逃脱死亡命运的最后一次机会,稍后GC将对F-Queue中的对象进行第二次小规模的标记,如果对象要在finalize()中成功拯救自己——只要重新与引用链上的任何一个对象建立关联即可,譬如把自己(this关键字)赋值给某个类变量或者对象的成员变量,那在第二次标记时它将被移除出“即将回收”的集合;如果对象这时候还没有逃脱,那基本上它就真的被回收了

 

Finalize方法具有以下四个特点:

  1. 永远不要主动调用某个对象的finalize方法,该方法应该交给垃圾回收机制调用。

  2. Finalize方法合适被调用,是否被调用具有不确定性,不要把finalize方法当做一定会执行的方法,

  3. 当JVM执行课恢复对象的finalize方法时,可能是改对象或系统中其他对象重新变成可达状态

  4. 当JVM调用finalize方法出现异常时,垃圾回收机制不会报告异常,程序继续执行。

 


注意点:

由于finalize方法不一定被执行,那么我们想清理某各类里打开的资源时,则不要方法finalize方法中。


实例说明:

640?wx_fmt=png

运行结果可以看出,SAVE_HOOK对象的finalize()方法确实被GC收集器触发过,并且在被收集前成功逃脱了。另外一个值得注意的地方是,代码中有两段完全一样的代码片段,执行结果却是一次逃脱成功,一次失败,这是因为任何一个对象的finalize()方法都只会被系统自动调用一次,如果对象面临下一次回收,它的finalize()方法不会被再次执行,因此第二段代码的自救行动失败了。

需要特别说明的是,上面关于对象死亡时finalize()方法的描述可能带有悲情的艺术色

彩,笔者并不鼓励大家使用这种方法来拯救对象。相反,笔者建议大家尽量避免使用它,因为它不是C/C++中的析构函数,而是Java刚诞生时为了使C/C++程序员更容易接受它所做出的一个妥协。它的运行代价高昂,不确定性大,无法保证各个对象的调用顺序。有些教材中描述它适合做“关闭外部资源”之类的工作,这完全是对这个方法用途的一种自我安慰。finalize()能做的所有工作,使用try-finally或者其他方式都可以做得更好、更及时,所以笔者建议大家完全可以

忘掉Java语言中有这个finalize方法的存在。

参考:《Java虚拟机》、《疯狂Java讲义》

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/191705.html原文链接:https://javaforall.net

(0)
上一篇 2026年1月26日 下午11:22
下一篇 2026年1月27日 上午7:01


相关推荐

  • Python-opencv读取深度图像

    Python-opencv读取深度图像由于实验需要用到Kinect2.0采集的深度图像,但是用以下程序读取深度图片的时候显不方便观察temp_img=’cup_depth.png’depth_filename=os.path.join(image_dir,depth_img)temp_filename=os.path.join(image_dir,temp_img)im…

    2022年5月24日
    209
  • Java 删除文件以及文件夹删除不了的问题

    Java 删除文件以及文件夹删除不了的问题问题所在今天在编写一个项目,流程是先创建一个临时文件夹存放生成的文件,再经过压缩导出,待导出成功后删除临时文件夹,但是怎么也删除不了,还以为是写的删除方法有问题,找来找去,试了很多方法也删除不了本来以为是打包的流没关闭,但是发现流都是关闭的,后来发现,是在生成的方法里,直接newFileWriter出来的,没有关闭,在这里提醒一下,关于操作文件或者文件夹一定都会用到流,所以用到的流一…

    2022年6月7日
    34
  • SpringBoot+Nacos实现配置中心

    SpringBoot+Nacos实现配置中心Nacos 配置中心 你值得拥有

    2026年3月17日
    2
  • CSS简单的图片居中

    CSS简单的图片居中图片的居中显示 css 有很多方法 但在很多情况下有的方法无效 这是件很头疼的事情 比如一般设置图片属性 text align center 水平居中 但这个方法经常无效 很多前端工程师都有研究过或者说是搜索过 CSS 图片居中方法吧 但其实 CSS 图片居中有多种不同的情况 也有多种不同的解决方法 具体方法如下所示 图片居中又分为水平居中和垂直居中提示 在你开始阅读以下内容之前 你可以先了解 CSS 图片的基础内容 一 水平居中 1 单独文字垂直居中我们只需要设置 CSS

    2026年3月18日
    2
  • js算法初窥03(搜索及去重算法)

    前面我们了解了一些常用的排序算法,那么这篇文章我们来看看搜索算法的一些简单实现,我们先来介绍一个我们在实际工作中一定用到过的搜索算法——顺序搜索。1、顺序搜索其实顺序搜索十分简单,我们还是以第一篇

    2022年3月25日
    43
  • c++ priority queue_priority

    c++ priority queue_priority既然是队列那么先要包含头文件#include<queue>优先队列具有队列的所有特性,包括基本操作,只是在这基础上添加了内部的一个排序,它本质是一个堆实现的定义:priority_queue<Type,Container,Functional>Type就是数据类型,Container就是容器类型(Container必须是用数组实现的容器,比如vector,deque等等,但不能用

    2025年8月24日
    10

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号