I/O 高级

从终结器迁移到确定性资源清理

用 AutoCloseable 替代终结机制,仅将 Cleaner 用作防御性后备方案。

✕ Finalization
@Override
protected void finalize() throws Throwable {
    nativeHandle.release();
}
✓ Java 9+
final class NativeResource implements AutoCloseable {
    private static final Cleaner CLEANER = Cleaner.create();

    private static final class State implements Runnable {
        private final long handle;

        State(long handle) {
            this.handle = handle;
        }

        @Override
        public void run() {
            release(handle);
        }
    }

    private final Cleaner.Cleanable cleanable;

    NativeResource(long handle) {
        cleanable = CLEANER.register(this, new State(handle));
    }

    @Override
    public void close() {
        cleanable.clean();
    }
}
发现此代码有问题? 告诉我们。
⏱

确定性

Try-with-resources 会在已知时机释放资源。

🛡

生命周期更安全

避免终结器复活和不可预测的执行顺序。

🧹

防御性后备方案

Cleaner 无需重写 finalize() 即可回收泄漏的资源。

旧方式
重写 finalize()
现代方式
AutoCloseable 和 Cleaner
自 JDK
9
难度
高级
从终结器迁移到确定性资源清理
可用

Cleaner 和终结机制弃用自 JDK 9 起可用(2017 年 9 月)

终结机制已被弃用并计划移除,既不能及时清理,也无法保证可靠的执行顺序。实现 AutoCloseable,使调用者可通过 try-with-resources 在确定的时机释放资源。对于泄漏的资源,Cleaner 可作为最后手段调用同一个幂等清理操作;该操作不得持有已注册对象。