finalizer와 cleaner 사용을 피하라
finalizer와 cleaner 사용을 피하라
자바의 객체 소멸자
1. finalizer (자바 8까지)
예측 불가능하고, 상황에 따라 위험할 수도 있어 일반적으로 불필요
2. cleaner (자바 9~)
finalizer보다는 덜 위험하지만 마찬가지로 예측 불가능, 느림, 일반적으로 불필요하다.
어째서 불필요한지?
1. finalizer와 cleaner는 즉시 수행된다는 보장이 없다.
즉, 두 가지로는 제때 실행되어야 하는 작업은 절대
할 수 없다.
ex)
파일 닫기의 경우, 동시에 열 수 있는 파일 개수에 한계가 있기 때문에,
finalizer나 cleaner가 제 때 실행되지 않는다면, 새로운 파일을 열지 못하게 될 수 있다.
2. 수행 여부를 보장하지 않는다.
접근할 수 없는 일부 객체에 딸린 종료 작업을 전혀 수행하지 못한 채 프로그램이 중단될 수 있다.
3. finalizer 동작 중 발생한 예외는 무시되며, 처리할 작업이 남았더라도 그 순간 종료된다.
4. 성능이 안좋다.
ex)
AutoCloseable 객체를 가비지 컬렉터가 수거하는 시간 : 12ns
finalizer : 550ns
대체 방안
AutoCloseable을 구현하고 인스턴스를 다 쓰면 close 메소드를 호출한다.
close 메소드에는 객체가 더 이상 유효하지 않음을 필드에 기록하고,
다른 메서드는 이 필드를 검사해서 객체가 닫힌 후에 불렸다면,
IllegalStateException을 던진다.
그렇다면 finalize와 cleaner는 어디에 쓰이는가 ?
- 자원의 소유자가 close 메서드를 호출하지 않는 것에 대비한 안전망 역할
즉, 어찌되건 자원 화수를 해주기 때문에 아예 안하는 것보단 낫다. - 네이티브 피어와 연결된 객체
네이티브 피어란?
일반 자바 객체가 네이티브 메서드를 통해 기능을 위임한 네이티브 객체.
네이티브 메서드는 Java 이외의 언어로 만들어진 어플리케이션이나 라이브러리가 상호작용할 수 있도록 연결시켜주는 인터페이스이다.
쉽게 말해, 다른 언어와 연결해주는 객체
네이티브 피어는 자바 객체가 아니라서 가비지 컬렉터로 처리할 수 없다.
따라서 cleaner나 finalizer가 처리하기 적당한 작업이다.
단, 성능 저하를 감당할 수 있고 네이티브 피어가 심각한 자원을 가지고 있지 않을 때 사용 가능
(아이템 66. 네이티브 메서드는 신중히 사용하라 -> 네이티브 메서드 성능 구림)