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
난이도
고급
JDK 지원
Finalizer에서 결정론적 리소스 정리로
사용 가능
Cleaner와 finalization 지원 중단은 JDK 9 (2017년 9월)부터 제공
동작 원리
Finalization은 제거를 위해 지원 중단되었으며 신속한 정리도 신뢰할 수 있는 순서도 보장하지 않습니다. 호출자가 try-with-resources로 리소스를 결정론적으로 해제할 수 있도록 AutoCloseable을 구현합니다. 누수된 리소스의 경우 Cleaner가 최후 수단으로 동일한 멱등 정리 작업을 호출할 수 있습니다. 이 작업은 등록된 객체를 참조해 유지해서는 안 됩니다.
관련 문서
증명