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有一个非常严重的性能损耗。
//构建对象使用后不能再次被实例化
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
2024-03-01
2024-03-01
2024-03-01
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0