第二章:FileCleanable源码逐行解读现在,让我们聚焦于您提供的FileCleanable源码,逐层拆解其精妙设计。 目的:从FileDescriptor中移除FileCleanable。这样,即使FileInputStream对象之后被GC,也不会再触发FileCleanable的清理动作。 构造器内部调用FileCleanable.register(fdo)。FileCleanable捕获fdo的fd/handle,创建自身实例,并将其注册到fdo的清理列表中。 调用FileCleanable.unregister(fdo),从fdo中移除FileCleanable。 GC发现该对象仅被FileCleanable的虚引用持有,将其标记为虚可达。GC将FileCleanable加入Cleaner的清理队列。
通过这种方式,FileDescriptor向JDK内部的其他组件(如NIO包、FileCleanable)暴露了必要的操作能力,例如:set/get:读写fd和handle。 registerCleanup/unregisterCleanup:注册和注销清理器,这是与FileCleanable协同工作的关键。close:执行关闭操作。 4.2自动清理:与FileCleanable的协同正如前文对FileCleanable的分析,FileDescriptor内部持有一个PhantomCleanable引用:展开代码语言:TXTAI代码解释 清理:如果用户忘记关闭流,当FileDescriptor对象变得虚可达时,FileCleanable的performCleanup方法会被Cleaner线程调用,强制关闭fd/handle。 它通过SharedSecrets,与JDK内部的清理器(FileCleanable)、NIO等模块建立了高效、安全的通信桥梁。它通过显式关闭与自动清理的双重机制,最大限度地防止了宝贵的系统资源泄漏。
注册清理器:FileCleanable.register(fd);这是防止资源泄漏的最后一道防线。 如果用户忘记调用close(),当FileInputStream对象被垃圾回收时,FileCleanable会确保底层的fd被正确关闭。 最后,它会调用fd.close(),执行真正的系统调用关闭fd,并注销之前注册的FileCleanable,防止重复关闭。 4.2自动清理作为后备如前所述,FileCleanable.register(fd)提供了一个安全网。即使开发者疏忽了close(),JVM也能在对象被回收时进行清理。 安全性:通过FileDescriptor的引用跟踪和FileCleanable的双重保险,最大限度地防止了系统资源泄漏。
Invalidfilepath");}this.path=file.getPath();this.fd=newFileDescriptor();fd.attach(this);open(this.path,append);FileCleanable.register FileCleanable.register(fd):这是JDK9引入的清理器(Cleaner)机制的一部分。 5.2FileCleanable:自动清理的最后防线展开代码语言:TXTAI代码解释FileCleanable.register(fd);Cleaner机制:这是JDK9用来替代finalize()方法的现代化