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. 无法控制传入的回收执行逻辑,可能导致性能问题。
相关推荐
考虑考虑2 分钟前
nginx路由重写
运维·后端·自动化运维
曹牧17 分钟前
C#:空合并运算符
java·前端·数据库
布吉岛的石头40 分钟前
Java 程序员第 50 阶段2:预训练的目标函数:自回归语言建模本质
java·开发语言·人工智能·深度学习·回归·transformer
golang学习记1 小时前
IDEA 2026年的玩法已经完全不同
java·ide·intellij-idea
JaguarJack1 小时前
PHP 紧急修复两项严重 RCE 漏洞,8.2 至 8.5 用户应立即升级
后端·php·服务端
BingoGo1 小时前
PHP 紧急修复两项严重 RCE 漏洞,8.2 至 8.5 用户应立即升级
后端·php
紧跟先前的步伐1 小时前
Go AI Agent 实战 05|Temperature 与生成参数:让模型输出可控
java·人工智能·golang
金銀銅鐵1 小时前
[Java] 展示添加元素时 ArrayList 的内部变化
java·后端·ai编程
斌糖雪梨2 小时前
spring auth 核心流程详解
java·后端·spring
高频因子挖掘机3 小时前
本地已有一年历史数据,第二天更新别只拉“昨天一天”:量化 K 线增量同步实践
后端·github·api