最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
Java避免使用finalizer和Cleaner代码详解
时间:2021-03-29 编辑:袖梨 来源:一聚教程网
本篇文章小编给大家分享一下Java避免使用finalizer和Cleaner代码详解,文章代码介绍的很详细,小编觉得挺不错的,现在分享给大家供大家参考,有需要的小伙伴们可以来看看。
java9之前finapzer,java9使用cleaner代替了finapzer。相比finapzer,cleaner(它存在于一个独立类Cleaner中,需要时候注入到对应类中即可)不会污染API而且cleaner有类库可以控制它的线程(它两都在后台线程中执行)。
避免使用的原因:
行为的不稳定性
它两都不能保证及时的执行,从方法可达到(对象被置空了)开始到最终的执行,时间是任意长的。所以千万不要使用他们来更新重要的持久状态,如释放流资源、分布式锁等。
System.gc和System.runFinapzation这两个方法会增加finapzer和cleaner被执行的机会,但是不保证一定会执行。唯一能保证它两会被执行的两个方法(System.runFinapzersOnExit和Runtime.runFinapzersOnExit)有致命的缺陷,已经被废除很久了。
移植性问题
不同的JVM堆垃圾回收的算法不同,如果程序依赖finapzer或者cleaner被执行的时间点,那么程序的表现可能截然不同
性能问题
finapzer和cleaner有一个非常严重的性能损耗。
安全问题
finapzer中如果出现异常会导致线程终止,但是不会打印线程轨迹甚至警告都不会打印出来,而且使正在销毁的对象处于破坏状态,另一个线程如果使用这个破坏状态的对象会出现行为的不确定性。cleaner没有这个问题。
finapzer攻击:利于finapzer方法,构建出恶意子类对象,非法调用父类方法。final类不会被构建恶意子类,所以不会遭到finapzer攻击。对于非final类,重写一个空的finapzer方法并用final修饰来防止finapzer攻击。
//构建对象使用后不能再次被实例化 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方法的时候,finapzer和cleaner可以充当安全网,虽然不能保证及时的释放资源,但是迟一点释放总比永远不释放要好。要使用这样的安全网就要认证的考虑清除是否值得付出这样的代价。所以Java一些AutoCloseable实现中都添加了安全网。
这是FileOutputStream的源码
回收本地对等体对象
本地对等体:java操作native方法其实是委托给一个本地对等体对象,使用完成后java对象会被GC回收,但是这个对等体对象不是java对象不会被会GC回收。如果这个对象性能可以接受,而且没有需要及时释放的资源那么就可以使用finapzer或者cleaner进行回收了。但是如果这个对等体性能无法接受且拥有必须被及时终止的资源,那么就需要提供一个close方法了。
-
下一个: vue配置请求多个服务端解决方法代码
相关文章
- SpringBoot自定义bean绑定解析 10-24
- Javaweb工程运行报错HTTP Status 404解决教程 10-20
- JAVA获取jvm和操作系统相关信息方法 10-20
- BeanFactory和FactoryBean的区别讲解 10-20
- 微信小程序的宿主环境实现教程 10-10
- dispatchEvent解决重叠元素响应事件教程 10-10