返回顶部
首页 > 资讯 > 后端开发 > Python >Java 为什么要避免使用finalizer和Cleaner
  • 645
分享到

Java 为什么要避免使用finalizer和Cleaner

2024-04-02 19:04:59 645人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

目录避免使用的原因:行为的不稳定性移植性问题性能问题安全问题两个用处:安全网回收本地对等体对象java9之前finalizer,java9使用cleaner代替了finalizer。

java9之前finalizer,java9使用cleaner代替了finalizer。相比finalizer,cleaner(它存在于一个独立类Cleaner中,需要时候注入到对应类中即可)不会污染api而且cleaner有类库可以控制它的线程(它两都在后台线程中执行)。

避免使用的原因:

行为的不稳定性

它两都不能保证及时的执行,从方法可达到(对象被置空了)开始到最终的执行,时间是任意长的。所以千万不要使用他们来更新重要的持久状态,如释放流资源、分布式等。

System.GC和System.runFinalization这两个方法会增加finalizer和cleaner被执行的机会,但是不保证一定会执行。唯一能保证它两会被执行的两个方法(System.runFinalizersOnExit和Runtime.runFinalizersOnExit)有致命的缺陷,已经被废除很久了。

移植性问题

不同的JVM堆垃圾回收的算法不同,如果程序依赖finalizer或者cleaner被执行的时间点,那么程序的表现可能截然不同

性能问题

finalizer和cleaner有一个非常严重的性能损耗。

安全问题

  • finalizer中如果出现异常会导致线程终止,但是不会打印线程轨迹甚至警告都不会打印出来,而且使正在销毁的对象处于破坏状态,另一个线程如果使用这个破坏状态的对象会出现行为的不确定性。cleaner没有这个问题。
  • finalizer攻击:利于finalizer方法,构建出恶意子类对象,非法调用父类方法。final类不会被构建恶意子类,所以不会遭到finalizer攻击。对于非final类,重写一个空的finalizer方法并用final修饰来防止finalizer攻击。

//构建对象使用后不能再次被实例化
public class Demo{
  private boolean flag = true;
  //防止实例化
  public Demo() {
    if (flag){
      throw new RuntimeException("不准许再次创建对象");
    }
  }
  public void say() {
    System.out.println("DemoUtils.say");
  }
}
//构建非法子类
class Demo2 extends Demo{
  public Demo2(){}
  //构建finalizer攻击
  @Override
  protected void finalize() throws Throwable {
    //会调用父类方法
    this.say();
    System.exit(0);
  }
  public static void main(String[] args) throws InterruptedException {
    try {
      //创建子类对象必然会调用父类构造,所以会发生异常
      //但是在gc中还是执行了父类的方法
      Demo demo = new Demo2();
      demo.say();
    } catch (Exception e) {
      System.out.println(e);
    }
    System.gc();
    //给垃圾回收提供时间
    Thread.sleep(5000);
  }
}
//运行结果
java.lang.RuntimeException: 不准许再次创建对象
DemoUtils.say

两个用处:

安全网

当资源的所有者忘记使用close方法的时候,finalizer和cleaner可以充当安全网,虽然不能保证及时的释放资源,但是迟一点释放总比永远不释放要好。要使用这样的安全网就要认证的考虑清除是否值得付出这样的代价。所以Java一些AutoCloseable实现中都添加了安全网。

这是FileOutputStream的源码

回收本地对等体对象

本地对等体:java操作native方法其实是委托给一个本地对等体对象,使用完成后java对象会被GC回收,但是这个对等体对象不是java对象不会被会GC回收。如果这个对象性能可以接受,而且没有需要及时释放的资源那么就可以使用finalizer或者cleaner进行回收了。但是如果这个对等体性能无法接受且拥有必须被及时终止的资源,那么就需要提供一个close方法了。

以上就是Java 为什么要避免使用finalizer和Cleaner的详细内容,更多关于Java 避免使用finalizer和Cleaner的资料请关注编程网其它相关文章!

--结束END--

本文标题: Java 为什么要避免使用finalizer和Cleaner

本文链接: https://lsjlt.com/news/122549.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Java 为什么要避免使用finalizer和Cleaner
    目录避免使用的原因:行为的不稳定性移植性问题性能问题安全问题两个用处:安全网回收本地对等体对象java9之前finalizer,java9使用cleaner代替了finalizer。...
    99+
    2024-04-02
  • Java避免使用finalizer和Cleaner的原因是什么
    这篇文章主要介绍了Java避免使用finalizer和Cleaner的原因是什么,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。java9之前finalizer,java9使用...
    99+
    2023-06-14
  • javascript为什么要避免使用eval()和with()
    这篇文章将为大家详细讲解有关javascript为什么要避免使用eval()和with(),小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。避免使用eval()和with()with() 会在全局范...
    99+
    2023-06-17
  • java为什么避免使用枚举
    在Java中,枚举是一种特殊的数据类型,用于定义一组有限的常量。虽然枚举在某些情况下非常有用,但也有一些情况下建议避免使用枚举,原因...
    99+
    2023-08-30
    java
  • Redis为什么要避免big key
    这篇文章主要介绍了Redis为什么要避免big key,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。避免 big keyRedis 执行命令是单线程的,这意味着 Redis ...
    99+
    2023-06-27
  • Vue中为什么要避免同时使用v-for和 v-if
    这篇文章主要介绍了Vue中为什么要避免同时使用v-for和 v-if,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。v-for 遍历避免同时使用 v-if为什么要避免同时使用&...
    99+
    2023-06-26
  • JavaScript为什么避免使用with()
    这篇文章主要为大家展示了“JavaScript为什么避免使用with()”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“JavaScript为什么避免使用with...
    99+
    2024-04-02
  • Vue3使用需要避免的错误是什么
    本篇内容主要讲解“Vue3使用需要避免的错误是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Vue3使用需要避免的错误是什么”吧!使用Reactive声明原始值数据声明在过去都是非常直接的,...
    99+
    2023-07-06
  • 服务器租用要避免什么陷阱
    不要被低价所诱惑:一些服务商可能会以非常低廉的价格来吸引客户,但可能会降低服务质量或隐藏一些额外费用。 不要忽视服务协议:在...
    99+
    2024-04-26
    服务器
  • 如何避免Java异常作为控制流使用
    这篇文章主要讲解了“如何避免Java异常作为控制流使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何避免Java异常作为控制流使用”吧!Java是一种通用的编程语言,它有着许多不同的方案...
    99+
    2023-06-16
  • java如何避免不必要的使用受检异常
    这篇文章主要介绍了java如何避免不必要的使用受检异常,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。避免不必要的使用受检异常检查异常强制调用者处理异常情况,因为如果没有,编译...
    99+
    2023-06-08
  • 为什么Java需要Shell和NPM?
    Java是一种广泛使用的编程语言,它在企业级应用开发中发挥着重要作用。然而,在Java的开发过程中,我们不可避免地需要用到一些其他工具,比如Shell和NPM。那么,为什么Java需要这些工具呢?本文将为您解答这个问题。 一、Shell S...
    99+
    2023-11-12
    shell npm http
  • 为什么要避免大事务以及大事务如何解决?
    什么是大事务 运行时间比较长,长时间未提交的事务就可以称为大事务 大事务产生的原因 操作的数据比较多 大量的锁竞争 事务中有其他非DB的耗时操作 。。。 大事务造成的影响 并发情况下,数据库连接池容易被撑爆 锁定太多的数据,...
    99+
    2022-01-02
    为什么要避免大事务以及大事务如何解决?
  • 为什么div css布局命名时要尽量避免下划线
    这篇文章主要介绍“为什么div css布局命名时要尽量避免下划线”,在日常操作中,相信很多人在为什么div css布局命名时要尽量避免下划线问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望...
    99+
    2024-04-02
  • Redis为什么要避免执行时间复杂度高的命令
    这篇文章主要为大家展示了“Redis为什么要避免执行时间复杂度高的命令”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Redis为什么要避免执行时间复杂度高的命令”这篇文章吧。避免执行时间复杂度高...
    99+
    2023-06-27
  • Java开发为什么需要使用UML
    这篇文章主要介绍Java开发为什么需要使用UML,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!知道UML造成了怎样的局面大混乱吗?知道什么样的功能是UML拥有但Java不具备的吗?知道我们为什么需要除JAVA外的另一...
    99+
    2023-06-03
  • 为什么vue要和nodejs一起使用
    前端开发中,由于业务逻辑越来越复杂,单纯的app就更难以胜任,为了提高开发效率和质量,后端也要为前端提供更多灵活的数据支持,这就涉及到跨域和服务器的简洁性问题。由于前端JavaScript语言的快速发展,人们诞生了新一代的前端服务器端技术,...
    99+
    2023-05-14
  • 为什么要使用redis
    这篇文章给大家分享的是有关为什么要使用redis的内容。小编觉得挺实用的,因此分享给大家做个参考。一起跟随小编过来看看吧。为什么要使用redis?redis数据库是将数据存储在内存中的,并且读写内存的速度要...
    99+
    2024-04-02
  • 为什么要使用MySQL
    这篇文章给大家分享的是有关为什么要使用MySQL的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。什么是MySQL  MySQL原本是一个开放源码的关系数据库管理系统,原开发者为瑞典...
    99+
    2024-04-02
  • 为什么要使用GraphQL
    这篇文章主要介绍“为什么要使用GraphQL”,在日常操作中,相信很多人在为什么要使用GraphQL问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”为什么要使用GraphQL”...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作