[아이템 8] finalizer 와 cleaner 사용을 피하라

ajufresh·2020년 3월 9일
0

Effective Java 3/E

목록 보기
8/9
post-thumbnail

블로그에 게시하는 위 글은 전체적인 내용 정리가 아닌
책을 읽으면서 새로 알게된 내용이나 제가 중요하다고 생각하는 내용을 정리한 글입니다.

객체 소멸자

finalizer

예측할 수 없고, 상황에 따라 위험할 수도 있다. (오동작, 낮은 성능, 이식성 문제의 원인 제공을 하기도 함)
쓰지 않는게 좋다.

cleaner

finalizer의 대안으로 소개되었지만,
여전히 예측할 수 없고, 느리고, 일반적으로 불필요하다.

사용을 피해야하는 이유

  • 실행되기까지 얼마나 걸릴지 알 수 없다.
    -> 제때 실행해야하는 작업에는 사용할 수 없다.
  • 수행여부를 보장하지 않는다. 보장해주는 메소드가 있지만(System.runFinalizersOnExit, Runtime.runFinalizersOnExit) 결함이 심하다.
    -> 영구적으로 수정하는 작업에 사용할 수 없다.
  • finalizer 동작 중 발생하는 예외는 무시된다.
  • 성능적으로 문제가 있다.
  • finalizer 공격에 노출되어 보안 문제를 일으킬 수도 있다.
    -> GC가 수집하지 못하게 막을 수 있기 때문에 일그러진 객체가 만들어질 수도 있다.

소멸자의 대안

종료해야할 자원을 담고 있는 클래스가 있다면,
AutpCloseable을 구현하고 close()를 호출한다. (try-catch문을 사용하면 더 좋다)
그 이후에 다른 메소드에서 호출하면 예외를 발생시킨다.

소멸자를 사용하는 곳

1. close()를 호출하지 않는 경우를 대비한 안전망

아예 회수를 안하는 것 보단 늦게라도 하는 것이 낫기 때문이다.
ex. FileInputStream, FileOutputStream, ThreadPoolExcutor

2. 네이티브 피어와 연결된 객체

네이티브 피어

일반 자바 객체가 네이티브 메서드를 통해 기능을 위임한 네이티브 객체
-> 자바 객체가 아니기 때문에 GC는 존재를 알 수 없다.
단, close()도 사용이 가능하니 무엇을 쓸지 고민하고 사용해야한다.

결론

소멸자는 중요하지 않은 네이티브 자원 회수 이외의 용도로는 사용하지 않는 것이 좋다.

profile
공블로그

0개의 댓글