I/O 고급

Finalizer에서 결정론적 리소스 정리로

Finalization을 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는 알려진 시점에 리소스를 해제합니다.

🛡

더 안전한 생명 주기

Finalizer 부활과 예측 불가능한 실행 순서를 피합니다.

🧹

방어적 대안

Cleaner는 finalize()를 재정의하지 않고도 누수된 리소스를 회수할 수 있습니다.

이전 방식
finalize() 재정의
모던 방식
AutoCloseable과 Cleaner
JDK 버전
9
난이도
고급
Finalizer에서 결정론적 리소스 정리로
사용 가능

Cleaner와 finalization 지원 중단은 JDK 9 (2017년 9월)부터 제공

Finalization은 제거를 위해 지원 중단되었으며 신속한 정리도 신뢰할 수 있는 순서도 보장하지 않습니다. 호출자가 try-with-resources로 리소스를 결정론적으로 해제할 수 있도록 AutoCloseable을 구현합니다. 누수된 리소스의 경우 Cleaner가 최후 수단으로 동일한 멱등 정리 작업을 호출할 수 있습니다. 이 작업은 등록된 객체를 참조해 유지해서는 안 됩니다.