Cleaner:Java的一种新资源释放方式

引言

在JDK9中新增了Cleaner类,该类的作用是用于替代finalize方法,更有效地释放资源并避免内存泄漏。

基本概念和使用

JEP260提案中,封装了大部分Sun包内部的API之余,还引入了一些新的API,其中就包含着Cleaner这个工具类。
Cleaner承担着替换finalize方法的作用,为了解决finalize方法的性能问题、安全问题以及不可靠。

Cleaner 类的主要方法和属性

Cleaner类中,一共就三个外部方法,一个简单的工具类。

其中,在调用create方法时,就会新建一条线程,用于监听目标对象是否已经被回收。监听的逻辑则是用到了虚引用 以及引用队列 ,在虚引用中,要是一个对象变成不可达后,在GC前会将该对象的虚引用放入引用队列中。详细的步骤以及逻辑可以看这篇文章【Java引用规范】虚引用以及引用队列

如何创建和使用 Cleaner 对象

  1. 使用Cleaner.create()创建Cleaner对象。
  2. 调用cleaner.register()方法,传入监听的对象以及回收后要执行的逻辑。其中,逻辑中不能带有监听对象的引用,否则对象将永远无法被回收。

实际应用和示例

典型的 Cleaner 类使用场景和示例代码

在JDK1.2中,就已经有这个类的内部实现了,不过是在sun包中实现的。由于是内部类不建议在生产代码中直接使用。不过sun包下的Cleaner类和lang包下的Cleanr类的功能是类似的。

Cleaner在JDK中最典型的实现就是堆外内存的回收。我们申请到一个堆外内存后,是无法手动将该堆外内存进行显示的回收的,只能等待JVM来自动回收该内存。

其中,自动回收的操作就是使用到了Cleaner工具类,在DirectByteBuffer的构造方法中,申请到堆外内存后,就会将堆外内存地址、申请容量 以及实际内存大小 传入到Deallocator类中进行空间的回收。

Deallocator类集成了Runnable接口,在run方法中就会将对应地址的堆外内存回收。

优点和局限性

Cleaner 类相比 Finalizer 和 PhantomReference 的优势

类型 自动化清理 易用性 安全性 性能影响
Cleaner 开箱即用 更强 较小
Finalizer 开箱即用 较弱 较大
PhantomReference 需要与引用队列相结合,额外代码工作量 较弱 较小

Cleaner 类和手动调用Close方法的区别

操作 执行时机 确定性 是否自动化清理 资源泄漏风险
Cleaner 对象被回收时隐式调用 执行时机无法控制 低(只要对象不再可达,就会自动清理)
调用Close方法 代码显示调用 只要调用,一定执行 高(如果忘记调用 close 方法,可能会导致资源泄露)

Cleaner 类的潜在问题和限制

  1. 每注册一个Cleaner类,就会新开一条线程用于监听目标对象是否已经进入到引用队列。直到目标对象被回收后,新线程才结束。
  2. Cleaner回收时间点无法控制。
  3. 不能替换所有的资源释放,必要时还是需要显式执行Close方法。
  4. 无法控制传入的回收执行逻辑,可能导致性能问题。
相关推荐
Zane19943 分钟前
为什么 del 一个对象有时立刻消失,有时却纹丝不动?一文讲透引用计数与垃圾回收
后端·python
编码浪子8 分钟前
Rust 智能指针深度实战:Box/Rc/Arc/RefCell 选型决策与内存管理避坑
开发语言·后端·rust
电商API_1800790524729 分钟前
速卖通商品采集API技术文章
java·开发语言·c++·api·跨境电商·商品详情
郑州光合科技余经理32 分钟前
海外版外卖系统架构:订单怎么流转、权限怎么分
java·开发语言·前端·系统架构·uni-app·php·ai编程
提线木偶1 小时前
CORS 到底谁说了算?一份跨域配置的避坑指南
前端·后端
一木 之林1 小时前
五、C++新特性、关键字与编译原理
java·jvm·算法
han_hanker1 小时前
新手公司项目实战
java·maven
vHelios1 小时前
【电商项目】商品搜索开发复盘(3):搜索与封装实现逻辑思考与编写
java
AI人工智能+电脑小能手2 小时前
大白话说Java设计模式-37-中介者模式(源码剖析篇)
java·设计模式·线程池·中介者模式·源码分析·executor·applicationeventmulticaster
卷无止境2 小时前
Python的contextlib与 FastAPI 中的上下文管理
后端·python·fastapi