자바에서는 두 가지의 객체 소멸자인 finalizer 와 cleaner 를 제공함
그 중 finalizer 은 예측할 수 없고, 상홍에 따라 위험할 수 있어 일반적으로 불필요함
오동작 , 낮은 성능, 이식성 문제의 원인이 되기도 함
finalizer는 나름의 쓰임새가 몇가지 있긴 하지만, 기본적으로는 사용하지 말아야 함
그래서 자바9에서는 finalizer 를 deprecated 로 지정하고 cleaner를 그 대안으로 소개했다.
cleaner는 finalizer 보다는 덜 위험하지만 여전히 예측할 수 없고, 느리고, 일반적으로 불필요하다.
finalizer와 cleaner는 즉시 수행된다는 보장이 없어서 객체에 접근 할 수 없게 된 후 finalizer나 cleaner가 실행되기까지 얼마나 걸리는지 알수 없다.
예시로 파일 닫기를 finalizer 나 cleaner에 맡기면 중대한 오류를 일으킬수 있다.
시스템이 finalizer나 cleaner실행을 게을리해서 파일을 계속 열어둔 상태로 둔다면 새로운 파일을 열지 못해 오류가 날수 있다.
이거의 수행에 대해서는 가비지 컬렉터 알고리즘에 달렸음, 이는 가비지 컬렉터 구현마다 천차만별임
클래스에 finalizer 를 달아두면 인스턴스 자원 회수가 지연될수 있어서 원인을 알수 없는 OOM(OutOfMemory) error 를 일으키면서 죽을수도 있다.
프로그램 생명주기(life cycle)와 상관없는 상태를 정규적으로 수정하는 작업에서는 절대 finalizer 나 cleaner에 의존해서는 안된다.
또한 finalizer 동작 중 발생한 예외는 무시되며 처리할 작업이 남았더라도 그 순간 종료된다.
약 2가지가 있다고 책에 기재되어 있으며
1. 자원의 소유자가 close 메서도를 호출하지 않는 것에 대한 대비한 안전망 역할
자바 라이브러리의 일부 클래스에서 finalizer 를 제공하며
FileInputStream , FileOutputStream , ThreadPoolExecutor가 대표적임
2. 네이티브 피어(native peer)와 연결된 객체에서 사용
네이티브 피어란 일반 자바 객체가 네이티브 메소드를 통해 기능을 위임한 네이티브 객체를 말함
네이티브 피어는 자바 객체가 아니니 가비지 컬렉터는 그 존재를 알지 못함
그 결과 자바 피어를 회수 할 때 네이티브 객체까지 회수하지 못함
cleaner나 finalizer 가 나서스 처리하기에 적당한 작업임
단 성능저하를 감당할수 있고, 네이티브 피어가 심각한 자원을 가지고 있지 않을 때에만 해당함
그게 아니라면 close 메소드를 사용해야 함
AutoCloseable 를 구현하고 클라이언트에서 인스턴스를 다 쓰고 나면 close메소드를 호출하면 됨
- 일단은 속도가 지독하게 느리다.
속도는 약 5배 느리짐 ( 책 예제 설명에 기재되어 있음)
- finalizer 를 사용한 클래스는 finalizer 공격에 노출되어 보안문제를 일으킴
finalizer나 cleaner는 안전망 열할이나 중요하지 않은 네이티브 자원 회수용으로만 사용하고
사용하더라도 불확실성과 성능 저하에 주의해야함