Item 8. Finalizer & Cleaner
Finalizer와 Cleaner 사용을 피하라
Java에는 finalizer
와 cleaner
라는 두 가지 객체 소멸자가 존재한다.
하지만 두 소멸자 모두 예측할 수 없고, 상황에 따라 위험할 수 있기 때문에 사용을 피해야 한다.
finalizer
: Java 9부터 deprecated 됨cleaner
: Java 9부터finalizer
를 대체하기 위해 도입되었으나 여전히 위험하고 예측할 수 없음
이 두 소멸자는 C++의 destuctor
와 비슷해 보이지만, 다른 개념이기 때문에 다음과 같은 차이점이 존재한다.
C++:
destructor
는 객체의 생성을 하면 꼭 필요한 것으로 자원을 회수하는 보편적인 방법Java: 기본적으로 가비지 컬렉터가 자원 회수를 담당하며,
finalizer
와cleaner
는 즉시 수행된다는 보장이 없음
소멸자가 위험한 이유
위에서 설명했듯이 finalizer
와 cleaner
는 즉시 수행된다는 보장이 없다.
위 두 소멸자의 수행 여부는 가비지 컬렉터의 알고리즘에 따라 달라지기 때문에 예측할 수 없으며 가비지 컬렉터 구현마다 다르다.
때문에 테스트 환경에서는 정상적으로 동작하지만, 프로덕션 환경에서는 예상치 못한 문제를 일으킬 수 있다.
즉시 수행 미보장: 가비지 컬렉터의 알고리즘에 따라 달라지기 때문에 즉시 수행되지 않을 수 있음
예외 처리 문제:
finalizer
내부에서 발생한 예외는 무시되며, 처리할 작업이 남아있더라도 수행이 중단됨(cleaner
는 해당 문제가 발생하지 않음)성능 문제: 가비지 컬렉터가 자동으로 수거하는 시간에 비해 훨씬 오래 걸림
보안 문제: 생성이 완료되지 않은 객체의 하위 클래스의
finalizer
가 수행될 수 있음
finalizer
와 cleaner
의 사용
finalizer
와 cleaner
의 사용안전망 역할
만약 파일이나 스레드 등 종료해야 할 자원을 소멸시키기 위해선, 위의 두 소멸자를 사용하는 것보다 AutoCloseable
인터페이스를 구현하는 것이 더 좋다.
두 소멸자는 AutoCloseable
인터페이스의 close()
메서드를 호출하지 않는 것에 대비한 안전망 역할을 할 수 있다.
네이티브 피어
네이티브 피어란 일반 자바 객체가 네이티브 메서드를 통해 접근하는 네이티브 객체를 말한다.
네이티브 객체는 자바 객체가 아니여서 가비지 컬렉터가 회수하지 못하기 때문에 finalizer
와 cleaner
를 직접 사용하여 회수하는 것이 좋다.
Last updated
Was this helpful?