본문 바로가기
Language/Java

Effective Java 2장 - Item8: finalizer와 cleaner 사용을 피하라

by limeeggpapa 2025. 6. 15.

아이템 8: finalizer와 cleaner 사용을 피하라

  • 핵심 개념

finalize()(Java 9부터 deprecated)와 Cleaner는 자원 회수를 위해 사용하면 안 됩니다. 실행 시점이 불확실하고, 성능을 떨어뜨리며, 매우 위험합니다.

  • 장점 (이들을 피했을 때의 장점)
  1. 예측 가능한 자원 관리: try-with-resources를 통해 자원 해제가 즉시, 확실하게 이루어집니다.
  2. 성능 향상: finalizer는 GC의 부담을 가중시켜 성능을 저하합니다.
  3. 안정성: finalizer 내에서 예외가 발생하면 무시되고, 상태가 망가질 수 있습니다.
  • 단점 (finalizer/cleaner 자체의 단점)

언제 실행될지 모른다: GC가 수행될 때까지 실행이 지연되거나, 프로그램이 끝날 때까지 실행되지 않을 수도 있습니다.

성능이 나쁘다: 일반적인 자원 해제보다 훨씬 느립니다.

💡 예제 비교

파일 같은 시스템 자원을 닫을 때를 생각해봅시다.

❌ 잘못된 예

 

public class BadResource {
    // 이런 코드는 절대 작성하면 안 됩니다.
    @Override
    protected void finalize() throws Throwable {
        // 자원 정리를 finalizer에 의존하는 것은 매우 위험함
        System.out.println("Finalizer가 자원을 정리합니다... (언제 될지 모름)");
        // close();
    }
}

⭕ 잘된 예

 

// AutoCloseable 인터페이스를 구현하고, close 메서드를 제공
public class GoodResource implements AutoCloseable {
    @Override
    public void close() { // 클라이언트가 직접 호출할 수 있는 명시적인 종료 메서드
        System.out.println("자원을 즉시 정리합니다!");
    }
}

// 사용할 때는 try-with-resources 구문을 사용 (아이템 9)
try (GoodResource res = new GoodResource()) {
    // 자원 사용...
} // 이 블록을 벗어나는 순간 자동으로 close()가 호출됨
  • 핵심: 자원 정리는 AutoCloseable을 구현하고 try-with-resources를 사용하세요!