-
item 8 finalizer와 cleaner사용을 피하라책/이펙티브 자바 2022. 2. 18. 22:47
ITEM 8 finalizer와 cleaner사용을 피하라
finalizer는 기본적으로 쓰지 말아야 하며 java9에서는 사용자제 api로 지정했다
finalizer와 cleaner를 피하는 이유
- 즉시 실행된다는 보장이 없으며 실행 시점을 예측하기가 어렵다
- 상황에 따라 위험한 경우가 있어서 일반적으로는 불필요하다
- 정확한 시점에 실행되어야 하는 작업은 절대 할 수 없다
- 얼마나 빠르게 수행이 될지는 GC 알고리즘에 달려있고 GC 구현마다 천차만별이다
- 수행 시점 뿐 아니라 수행 여부도 보장하지 않는다
- 상태를 영구적으로 수정하는 작업에서는 절대 사용하지 말자
- DB 영구 락 해제를 맡겼다가 분산 시스템 전체가 서서히 멈출수도 있다
- 동작 중 발생한 에러는 무시되며 처리할 작업이 남아 있어도 그 순간 종료된다
- finalizer는 GC의 효율을 떨어뜨려 성능적으로도 비효율적이다
- finalizer를 사용한 클래스는 finalizer 공격에 노출되어 보안 문제가 발생할 수 있다
- 방어하고 싶다면 아무일도 하지 않는 finalizer 메서드를 final로 선언하자
대안은 무엇인가?
- 파일이나 스레드 등 종료해야 할 자원을 담고 있는 객체의 클래스에서 AutoCloseable을 구현
- 다 쓰고 나면 close 메서드를 호출해준다
- try-with-resources를 사용하여 에러 발생시 제대로 종료 하도록 처리
그럼 finalizer와 cleaner의 용도는 무엇인가?
- 자원의 소유자가 close 메서드를 호출하지 않을때 대비용으로 사용
- 바로 자원 회수를 한다는 보장은 없지만 나중에라도 해주는게 안하는것보다 나으니..
- 하지만 잘 생각해서 쓰자.. ex) FileInputStream, FileOutputStream, ThreadPoolExecutor
- 네이티브 피어와 연결된 객체에서 사용
- 네이티브 피어 : 일반 자바 객체가 네이티브 메서드를 통해 기능을 위임한 네이티브 객체
- 네이티브 피어는 자바 객체가 아니라 GC가 알지 못해서 회수가 불가능하다
- 이런 경우 finalizer와 cleaner를 사용해서 처리한다
- 하지만 성능 저하는 감수해야 한다
- 네이티브 피어가 사용하는 자원을 바로 회수해야 한다면 close 메서드를 써야된다
finalizer와 cleaner는 안전망 역할이며 중요하지 않은 네이티브 자원의 회수 용도로만 사용하자
물론 사용시 성능 저하에 주의해야 한다
'책 > 이펙티브 자바' 카테고리의 다른 글
item 10 equals는 일반 규약을 지켜 재정의하라 (0) 2022.02.22 item 9 try-finally보다는 try-with-resources를 사용하라 (0) 2022.02.21 item 7 다 쓴 객체 참조를 해제하라 (0) 2022.02.17 item 6 불필요한 객체 생성을 피하라 (0) 2022.02.16 item 5 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라 (0) 2022.02.15