Effect Java 제2판(Joshua Bloch / Addison Wesley) 을 공부하고 정리한 내용 입니다.
7. 파이널라이저(finalizer)의 사용을 피하자.
- 신속하게 실행된다는 보장이 없다.
객체가 사용할 수 없게 되는 시점부터 파이널라이저가 실행되는 시점까지는 긴 시간이 소요될 수 있다. 파이널라이저 내부에서는 실행 시간이 매우 중요한 작업을 절대 하지 말아야 한다는 것이다. - 파이널라이즈를 하는 동안 catch 되지 않은 예외가 발생하면 그 예외는 무시되고 그 객체의 파이널 라이즈는 종결된다.
- 파이널라이저를 사용하면 엄청난 성능 저하가 발생한다.
파일이나 스레드처럼 종결 작업이 필요한 자원을 갖는 객체들의 클래스에서는 파이널라이저 대신 무었을 써야 할까?
작업이나 자원을 정상적으로 종료하는 메소드만 별도로 추가하면 된다. 그리고 더 이상 필요 없는 각 인스턴스에 대해서 그 클래스의 클라이언트가 종료 메소드를 호출하도록 하면 된다.
파이널라이저는 어떤 경우에 사용하면 좋을까??
- 생성된 객체를 갖고 있는 코드에서 그 객체의 종료 메소드 호출을 빠뜨렸을 경우에 "안전망"의 역할을 하는 것이다.
즉, 클라이언트가 종료 메소드 호출에 실패하는 그런 경우(거의 없기를 바라지만)를 대비해서 파이널라이저를 사용한다. - 네이티브 피어(native peer) 객체와 관련이 있다.
네이티브 피어는 일반 자바 객체가 아니므로, 그것과 연관된 자바 피어 객체가 소멸되면 가비지 컬렉터가 알지 못하며 재활용 할 수도 없다. 따라서 이런 경우 파이널라이저가 적합한 수단이 된다.
"파이널라이저의 연쇄 호출(chaining)" 은 자동으로 실행되지 않는다는 것에 유의하자.
요약
- 종료 메소드 호출을 빼먹은 경우를 대비한 안전망의 역할이나, 또는 중요하지 않은 네이티브 자원을 종결하는 경우 외에는 파이널라이저를 사용하지 말자.
- 어쩔 수 없이 파이널라이저를 사용해야 하는 그런 경우에는 super.finalize()를 호출하는 것을 잊지 말자.
- 만일 안전망의 역할로 파이널라이저를 사용한다면, 부적절한 상황(자원 사요잉 끝나지 않은 객체를 파이널라이즈하는)을 메시지로 기록해야 한다는 것을 잊지 말자.
- public 이고 final이 아닌 클래스에 파이널라이저가 필요하다면, 파이널라이저 가디언의 사용을 고려하자. 서브 클래스의 파이널라이저에서 super.finalize 호출에 실패하더라도 파이널라이즈가 될 수 있기 때문이다.
'Programs > Java' 카테고리의 다른 글
모든 객체에 공통적인 메소드 - 9. equals 메소드를 오버라이드 할 때는 hashCode 메소드도 항상 같이 오버라이드 하자. (1) | 2012.11.05 |
---|---|
모든 객체에 공통적인 메소드 - 8. equals 메소드를 오버라이딩 할 때는 보편적 계약을 따르자. (0) | 2012.11.02 |
객체의 생성과 소멸 - 6. 쓸모 없는 객체 참조를 제거하자. (0) | 2012.11.01 |
객체의 생성과 소멸 - 5. 불필요한 객체의 생성을 피하자. (2) | 2012.10.30 |
객체의 생성과 소멸 - 4. private 생성자를 사용해서 인스턴스 생성을 못하게 하자. (1) | 2012.10.30 |