Intro::
이펙티브 자바 정리본입니다.
결론부터 말하자면 finalizer는 예측할 수 없고, 상황에 따라 위험할 수 있어 일반적으로 불필요합니다. 또한 cleaner도 finalizer보다는 덜 위험하지만, 여전히 예측할 수 없고, 느리고, 일반적으로 불필요합니다.
finalizer와 cleaner는 C++에서의 파괴자와는 다른 개념입니다. C++에서는 파괴자에서 자원 회수를 하지만 자바는 가비지 컬렉터가 이를 담당하기 때문입니다. 자바에서는 try-with-resources와 try-finally를 사용해 해결합니다.
사용하면 안되는 이유
- finalizer와 cleaner는 즉시 수행된다는 보장이 없기 때문에, 제때 실행되어야 하는 작업을 절대할 수 없습니다.
- 자바 언어 명세는 finalizer와 cleaner의 수행 시점뿐 아니라 수행 여부조차 보장하지 않습니다. 즉, 접근할 수 없는 일부 객체에 딸린 종료 작업을 전혀 수행하지 못한 채 프로그램이 중단될 수도 있다는 얘기입니다. 따라서 프로그램 생애주기와 상관없는, 상태를 영구적으로 수정하는 작업에서는 절대 finalizer와 cleaner에 의존해서는 안됩니다.
- 예시로 데이터베이스 같은 공유 자원의 영구 락 해제를 finalizer와 cleaner에 맡기면 분산 시스템 전체가 서서히 멈출것 입니다.
- finalizer와 cleaner는 심각한 성능 문제도 동반합니다.
- 안전망 방식에 비해 대단히 느립니다.
- finalizer를 사용한 클래스는 finalizer 공격에 노출되어 심각한 보안 문제를 일으킬 수 있습니다.
- 생성자나 직렬화 과정에서 예외가 발생하면, 이 생성되다만 객체에서 악의적인 하위 클래스의 finalizer가 수행될 수 있게 됩니다.
- final이 아닌 클래스를 finalizer 공격으로부터 방어하려면 아무 일도 하지 않는 finalize 메서드를 만들고 final로 선언합시다.
대안
- AutoCloseable을 구현해주고, 클라이언트에서 인스턴스를 다 쓰고 나면 close 메서드를 호출해주면 됩니다.
cleaner를 안전망으로 사용하는 AutoCloseable 클래스
public class Room implements AutoCloseable { private static final Cleaner cleaner = Cleaner.create(); // 청소가 필요한 자원. 절대 Room을 참조해서는 안 된다! private static class State implements Runnable { int numJunkPiles; // Number of junk piles in this room State(int numJunkPiles) { this.numJunkPiles = numJunkPiles; } // close 메서드나 cleaner가 호출한다. @Override public void run() { System.out.println("Cleaning room"); numJunkPiles = 0; } } // 방의 상태. cleanable과 공유한다. private final State state; // cleanable 객체. 수거 대상이 되면 방을 청소한다. private final Cleaner.Cleanable cleanable; public Room(int numJunkPiles) { state = new State(numJunkPiles); cleanable = cleaner.register(this, state); } @Override public void close() { cleanable.clean(); } }
// 잘 짜인 클라이언트 코드 public class Adult { public static void main(String[] args) { try (Room myRoom = new Room(7)) { System.out.println("안녕~"); } } }
질문
그럼 finalizer와 cleaner은 어디에 쓰는 건가??
- 자원의 소유자가 close 메서드를 호출하지 않는 것에 대한 안전망 역할
- 네이티브 피어와 연결된 객체 해제
References::
이펙티브 자바 / 조슈아 블로크 지음 (프로그래밍 인사이트)
Loading Comments...