Effective Java | #8. finalizer와 cleaner 사용을 피하라

보람·2022년 5월 12일
0

Effective-Java

목록 보기
9/25

자바의 두가지 객체 소멸자

  • finalizer : 예측X, 상황에 따라 위험할 수 있음
  • cleaner : finalizer 보다는 덜 위험, 여전히 예측X, 느리고, 일반적으로 불필요
  • 기본적으로 사용하지 말자
  • 자바에서는 try-with-resources(item-9)와 try-finally를 사용해 해결

좋지 못한 이유

  • 즉시 수행된다는 보장이 없어 finalizer와 cleaner로는 제때 실행돼야 하는 작업 불가능
    • ex) 동시에 열 수 있는 파일 개수에 한계가 있는 파일 닫기를 맡기면 중대한 오류를 일으킬 수 있다.
  • 자원 회수가 제멋대로 지연될 수 있다.
  • 예방 방법은 없으며 사용하지 않는 방법뿐
  • 상태 영구적 수정 작업에서는 절대 의존해서는 안됨
  • finalizer 동작 중 발생된 예외는 무시되며 남은 작업이 있어도 그 순간 종료
  • 심각한 성능 문제 동반
    • try-with-resources에 비해 약 50배 정도 느림
  • finalizer를 사용한 클래스는 finalizer 공격에 노출되어 심각한 보안 문제를 일으킬 수 있음
    • final이 아닌 클래스를 finalizer 공격으로부터 방어하려면 아무 일도 하지 않는 finalize 메서드를 만들고 final로 선언하자.

Autocloasble, close 를 대신 사용하기

  • try-with-resources를 사용하여 예외가 발생해도 제대로 종료되도록 한다
  • 각 인스턴스가 닫혔는지 추적하는 것이 좋음. 유효 필드에 기록, 닫힌 후 호출된 경우 IllegalStateException 호출

그럼 finalize, cleaner는 언제 쓰는겨..?0?

미회수된 자원의 안전망 역할

  • 늦게라도 회수하기 위함
  • 이런 안전망 역할이 필요한지에 대해서는 심사숙고하여 작성할 것

네이티브 자원 회수용

  • 네이티브 피어 : 일반 자바 객체가 네이티브 메서드를 통해 기능을 위함한 네이티브 객체
    • 네이티브 메서드는 C, C++과 같은 네이티브 언어로 작성된 메서드
  • 네이티브 피어는 자바 객체가 아니기 때문에 가비지 컬렉터가 이 친구를 알 수 X, 회수 불가능
    • 성능 저하를 감당할 수 있고 해당 객체가 심각한 자원을 가지고 있지 않다면 cleaner, finalizer가 나서서 처리하기에 적당한 작업
  • 즉시 회수를 원한다면 close 메서드 사용

cleaner와 finalize는 구현하기 나름이여서 까다롭고 구현하더라도 청소가 되리란 보장이 없다.

핵심 정리

cleaner(자바 8까지는 finalizer)는 안정망 역할이나 중요하지 않은 네이티브 자원 회수용으로만 사용하자. 몰론 이런 경우라도 불확실성과 성능 저하에 주의해야 한다.

profile
백엔드 개발자

0개의 댓글