자바는 객체 소멸자로 finalizer와 cleaner를 제공한다. 자바 9에서는 finalizer를 deprecated API로 지정하고 cleaner를 대안으로 소개했지만 cleaner도 사용하지 않는 것이 좋다.
소멸자는 객체가 GC에 의해 제거될 때 호출된다.
그럼 왜 사용하지 말라고 하는 것일까?
만약 파일 닫기가 제때 되지 않아 파일을 계속 열어둔다면 새로운 파일을 열지 못해 프로그램이 실패할 수 있다.
예를 들어 데이터베이스 같은 공유 자원의 락 해제를 finalizer나 cleaner에 맡겨놓으면 분산 시스템 전체가 서서히 멈출 것이다.
finalizer나 cleaner를 얼마나 신속히 수행할 지는 전적으로 가비지 컬렉터 알고리즘에 달렸으며, 이는 가비지 컬렉터 구현마다 다르다.
예외가 발생하여 마무리가 덜 된 객체를 다른 스레드에서 접근하게 될 수도 있다. cleaner를 사용하는 라이브러리는 자신의 스레드를 통제하기 때문에 이러한 문제가 발생하진 않는다.
AutoCloseable 을 구현하고 클라이언트에서 인스턴스를 다 쓰고 나면 close 메서드를 호출하는 것이다. (예외가 발생되어도 제대로 종료되도록 try-with-resources를 사용하는 것이 좋다.) 그리고 각 인스턴스는 자신이 닫혀있는지를 추적하는 것이 좋다. 객체가 더 이상 유효하지 않음을 필드에 기록하고 close 메서드에서 필드 값을 확인해 객체가 닫힌 후라면 IllegalStateException을 던지는 것이다.
안전망 역할
자원의 소유주가 close 메서드를 호출하지 않는 것에 대비한 안전망 역할이다. 호출되리라는 보장은 없지만 클라이언트가 하지 않은 자원 회수를 늦게라도 해주는 것이 아예 안 하는 것보다는 낫다.
네이티브 피어
네이티브 피어는 일반 자바 객체가 네이티브 메서드를 통해 기능을 위임한 네이티브 객체를 말한다. 네이티브 피어는 자바 객체가 아니니 gc 대상이 되지 못한다.
성능 저하를 감당할 수 없거나 즉시 반환해야 하는 자원이라면 close 메서드를 사용해야 한다.