///
Search
💡

item 8. finalizer와 cleaner 사용을 피하라 Avoid finalizers and cleaners

finalizer란?

finalizer는 finalize 메소드를 오버라이드하여 Garbage Collect 대상이 될 때 수행된다. 자바 9부턴 deprecated 되었고, Cleaner를 대안으로 지정한다.

finalizer 구현

@Override public void finalize() { // ... }
Java
복사

cleaner 구현

Cleaner 가 더 이상 사용되지 않을 때 등록된 스레드에서 정의된 클린 작업을 수행한다.
public class CleaningRequiredObject implements AutoCloseable { private static final Cleaner cleaner = Cleaner.create(); private static class CleanData implements Runnable { @Override public void run() { // 여기서 클린 작업 수행 } } private final CleanData; private final Cleaner.Cleanable cleanable public CleaningRequiredObject() { this.cleanData = new CleanData(); // 등록 this.cleanable = cleaner.register(this, state); } @Override public void close() { cleanable.clean(); } }
Java
복사
책에선 예측 불가능하고, 자주 위험하며, 일반적으로 쓸모없기 때문에 사용하지 말라고 한다. (cleaner도!)

finalizer 또는 cleaner를 쓰면 안 되는 이유

1.
자바는 finalizer의 수행 시점은 물론 수행 여부조차 보장해주지 않는다.
2.
try-with-resources 문에 비해 심각한 성능 저하가 있다.
그래서 기본적으로 '쓰지 말라고' 가이드한다.

그래도 쓸 곳 없을까요?

1.
클라이언트가 close 메소드를 호출하지 않을 경우를 대비한 안전망 역할이다.
finalizer 또는 cleaner가 동작할거란 보장은 없지만, 아무것도 안하는 것 보단 나을 수 있다. FileInputStream, FileOutputStream, ThreadPoolExecutor는 안전망 역할의 finalizer를 제공하는 라이브러리 중 하나다.
2.
네이티브 피어와 연결된 객체에서 사용할 수 있다.
네이티브 피어는 일반 자바객체가 네이티브 메서드를 통해 기능을 위임한 네이티브 객체를 말한다. 자바 객체가 아니므로 GC는 네이티브 객체의 존재조차 모른다. 이런 상황이라면 finalizer 또는 cleaner가 처리할 수 있다. 그러나 성능 저하를 감수할 수 있고 네이티브 피어가 그다지 중요하지 않은 자원을 가지고 있을 때에 해당한다. 그렇지 않다면 close 메서드를 활용해야한다.

용어정리

한글명
영어명
네이티브 피어
native peer
지각
tardiness
개심, 교정
reclaim