본문으로 바로가기
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.


종료자는 예측 불가능하며, 대체로 위험하고 일반적으로 불필요하다. 종료자를 사용하면 시스템 오류, 성능 문제, 이식성 문제가 발생할 수 있다. 종료자의 단점은 즉시 실행되리라는 보장이 전혀 없다는 것이다. 어떤 객체에 대한 모든 참조가 사라지고 나서 종료자가 실행되기까지는 긴 시간이 걸릴 수도 있다. 따라서 긴급한 작업을 종료자 안에서 처리하면 안된다. 예를 들어 종료자 안에 파일을 닫도록 하면 치명적이다. 


종료자 실행 시점은 GC 알고리즘에 좌우되는데, 이 알고리즘은 JVM 마다 크게 다르다. 


자바 명세에는 종료자가 즉시 실행되어야 한다는 문구도 없지만, 종료자가 결국에는 반드시실행되어야 한다는 문구도 없다. 따라서 종료자가실행되지 않은 객체가 남은 상태로 프로그램이 끝나게 되는 일도 충분히 가능하다. 그러므로 지속성이 보장되어야 하는 중요 상태 정보는 종료자로 갱신하면 안된다. 


종료자를 사용하면 프로그램 성능이 심각하게 떨어진다. 간단한 객체를 만들고 삭제하는데 5.6ns가 충분한데, 종료자를 붙이면 2,400ns로 늘어났다. 430배 가량이 프로그램이 느려졌다.


파일이나 스레드처럼 명시적으로 반환하거나 삭제해야 하는 자원을 포함하는 객체의 클래스는 어떻게 작성해야 하는 것일까 ? 그냥 명시적인 종료 메서드를 하나 정의하고, 더 이상 필요하지 않는 객체라면 클라이언트가 해당 메서드를 호출하도록 하라. 명시적인 종료 메서드의 예로는 Connection, Stream의 close() 가 있다. 명시적 종료 메소드는 보통 try-finally 문과 함께 쓰인다. 객체 종료를 보장하기 위해서다. 객체 사용 과정에서 예외가 던져져도 종료 메서드가 실행되도록 만들 수가 있다.


주의할 것은 자바 1.7부터 try-with-resource문을 지원하는데 이 문법을 사용하면 finally 블록을 사용하지 않아도 된다.


종료자는 정말 써먹을 데가 없는가 ? 적합한 곳은 2 군데가 있다.


1. 명시적 종료 메서드 호출을 잊을 경우에 대비하는 안전망으로서의 역할. 

2. 네이티브 피어와 연결된 객체를 다룰 때. 네이티브 피어는 일반 자바 객체가 네이티브 메서드를 통해 기능 수행을 위임하는 네이티브 객체를 말한다.


종료자를 사용할 때 주의할 것은 "종료자 연결"이 자동으로 이루어지지 않는다는 것이다. 어떤 크래스가 종료자를 갖고 있고 하위 클래스가헤당 메서드를 재정의 하는 경우, 하위 클래스의 종료자는 상위 클래스 종료자를 명시적으로 호출해야 한다. 상위 클래스의 종료자 호출을 잊으면 상위 클래스 종료자는 절대로 호출되지 않는다. 


정리하자면 자원 반환에 대한 최종적 안전장치를 구현하거나, 그다지 중요하지 않은 네이티브 자원을 종료시키려는 것이 아니라면 종료자는 사용하지 않는 것이 좋다. 굳이 종료자를 사용해야 하는 드문 상황에 처했다면 super.finalize 호출은 잊으면 안된다. 하위 클래스 정의가 가능한 public 클래스에 종료자를 추가해야 하는 상황이라면, 하위 클래스에서 실수로 super.finalize 호출을 잊어도 종료 작업이 진행될 수 있도록 종료 보호자 패턴을 도입하면 좋을지 고려해 봐야 한다.