Why?생길 수 있는 문제상황종료 작업을 전혀 수행하지 못한채 프로그램 중단 가능성심각한 성능 문제finalizer 공격에 노출되어 심각한 보안 문제 일으킬 수 있음종료해야 할 자원의 대책? AutoCloseable & try with resources언제 쓰냐 그럼 ?
기본적으로 쓰지 마라. ㅎ
Why?
- finalizer는 예측할 수 없고, 상황에 따라 위험할 수 있어 일반적으로 불필요함
- cleaner는 finalizer보다는 덜 위험하지만, 여전히 예측할 수 없고, 느리고, 일반적으로 불필요하다.
- finalizer와 cleaner는 즉시 수행된다는 보장이 없다.
생길 수 있는 문제상황
종료 작업을 전혀 수행하지 못한채 프로그램 중단 가능성
- finalizer에 의해서 객체를 close 한다면, 제대로 사용하지 않는 객체에 대해 close를 하지 못해서 OutOfMemoryError가 발생할 수 있음. 객체 수천 개가 finalizer 대기열에서 회수되기만을 기다리고 있는 그런 상황..
- finalizer 스레드가 다른 애플리케이션의 스레드보다 우선 순위가 낮아서 실행될 기회를 제대로 얻지 못한 것
- cleaner는 자신을 수행할 스레드를 제어할 수 있다는 면에서 조금 낫지만 그래도 즉각 수행 되리라는 보장이 없음
- finalizer 에서 예외가 일어나면 경고가 출력조차 되지 않음
심각한 성능 문제
- AutoCloseable 객체는 가비지 컬렉터가 수거하기 가지 12ns 걸리는 반면 finalizer 사용하면 550ns가 걸림
finalizer 공격에 노출되어 심각한 보안 문제 일으킬 수 있음
- 생성자나 직렬화 과정(readObject와 readResolve 메서드) 에서 예외가 발생하면, 이 생성되다 만 객체에서 악의적인 하위 클래스의 finalizer가 수행될 수 있게 됨
종료해야 할 자원의 대책? AutoCloseable & try with resources
언제 쓰냐 그럼 ?
- 클라이언트가 하지 않은 자원 회수를 늦게라도 해주는 것이 아예 안 하는 것보다는 나음
- 안전망 역할로 쓸 수 있음.(그러나 그럴만한 값어치가 있는지 심사 숙고한 후에)
- 네이티브 피어와 연결된 객체에서
cleaner(자바 8까지는 finalizer) 는 안전망 역할이나 중요하지 않은 네이티브 자원 회수용으로만 사용하자. 물론 이런 경우라도 불확실성과 성능 저하에 주의해야 함