java终结器_Java的终结器仍然存在

java终结器

当我第一次学习Java并从C ++过渡到Java时,我记得我经常被告知,经常读到它不应该像C ++析构函数那样对待Java终结器,也不应该依靠它。 该建议的频率和坚持性对我产生了影响,以至于我无法回忆起我上一次编写finalize()方法的经历,也无法回忆起我在编写,阅读,审阅,维护,修改和调试的Java代码。 但是直到最近,我还没有考虑finalize()影响 ,可能是因为我没有使用finalize() 。 最近对finalize()的经验已将Java终结器的效果从“学术练习”转变为“野外”的真实问题。

Object.finalize()的方法级Javadoc文档注释提供了有关Java终结器的一些有趣的细节。 首先提供对方法的总体描述,“当垃圾回收确定不再有对该对象的引用时,垃圾回收器将其调用在对象上。 子类会覆盖finalize方法来处置系统资源或执行其他清理。” 该Javadoc注释的另一部分警告了与Java终结器的使用通常相关的几个问题 :“ Java编程语言不能保证哪个线程将为任何给定对象调用finalize方法。 但是,可以保证,调用finalize的线程在调用finalize时不会持有任何用户可见的同步锁。 如果finalize方法引发了未捕获的异常,则该异常将被忽略,并且该对象的终结将终止。”

乔什·布洛赫(Josh Bloch)在《 有效的Java》中专门介绍了Java终结器这一主题。 Effective Java第二版的第7项标题简洁明了,“避免终结器”。 尽管有效Java中的许多项目都使用了动词,例如“ Prefer”或“ Consider”,但该项目使用了更强的动词“ Avoid”。 布洛赫(Bloch)确实列举了一些可能使用终结器的示例,但是他对仍然存在的内在问题的描述以及为减轻这些问题而需要考虑的许多事情,使我们大多数人都尽量避免使用它们。

Bloch以强调的( 粗体 )语句开始了有效的Java项目“ Avoid Finalizers”,“ Finalizers是不可预测的,通常是危险的,并且通常是不必要的。 “ Bloch强调开发人员不应“ 在终结器中做任何对时间要求严格的事情 ”,因为“不能保证[Java终结器将被立即执行”,并且他强调开发人员应“ 永远不要依赖终结器来更新关键的持久状态 ”。因为“根本无法保证[Java终结器]将被执行。” Bloch引用了终结器中的异常不会被捕获,并警告了这样做的危险,因为“未捕获的异常可能会使对象处于损坏状态。”

Bloch还描述了我最近使用过的Java终结器的负面影响。 他的“避免终结器”项强调(以粗体显示 ),“ 使用终结器会导致严重的性能损失 ”,因为“ 使用终结器创建和销毁对象”会花费更长的时间。 在我们的例子中,我们使用的是第三方库,该库在内部使用Java类finalize()方法来释放本机内存(C / C ++通过JNI )。 因为这些类中有很多这些对象带有finalize()方法,所以似乎处理Java终结的系统线程落后了,并且锁定了正在终结的对象。

垃圾收集受到了不利影响 ,因为收集者启动的频率比我们通常看到的还要频繁。 我们很快意识到垃圾收集日志表明垃圾收集问题,这些问题很难追溯到典型的堆大小问题或我们自己类的内存泄漏 。 使用jcmd <pid> GC.class_histogram GC.class_histogram对JVM进程运行非常有用的jcmd ,有助于我们快速了解潜在的罪魁祸首。 该类直方图显示了足够的java.lang.ref.Finalizer实例,以确保它在顶部排名第三。 由于该课程通常在课程直方图的下方,因此我什至通常不会看到或考虑它。 当我们意识到在类直方图中描述的前八个实例中的另外三个是第三方库中的三个类,并且它们实现了finalize()方法时,我们就能够解释行为并将其归咎于终结器 (四个直方图中排名前八位的类别中,这是一个相当安全的指责)。

Java语言规范第12.6节 (“类实例的完成”)中提供了一些与Java终结器相关的细节。 本节从描述Java终结器开始:“可以为对象调用的finalize()的特定定义称为该对象的终结器。 在垃圾回收器回收对象的存储之前,Java虚拟机将调用该对象的终结器。” 这里引用了Java语言规范这一节中描述的Java终结器的一些有意不确定的特征(我已经加了任何强调 ):

  • “Java编程语言没有规定如何尽快终结将被调用。”
  • “ Java编程语言没有指定哪个线程将为任何给定对象调用终结器。”
  • “终结器可以按任何顺序调用,甚至可以同时调用。”
  • “如果在完成过程中抛出未捕获的异常 ,则该异常将被忽略,并且该对象的完成将终止。”

我发现自己很喜欢与解决此问题的团队一起工作,因为我能够在“现实生活”中体验我只是从“学术”意义上阅读和了解的内容。 应用最喜欢的工具(例如jcmd )并应用以前的经验(例如识别出jcmd 类直方图中看起来不合适的东西 )来解决一个新问题总是很令人满意的。

翻译自: https://www.javacodegeeks.com/2017/03/javas-finalizer-still.html

java终结器

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值