이펙티브 자바/2장 객체 생성과 파괴

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

말랑공룡 2023. 12. 19. 10:29

 

- 자바는 finalizer와 cleaner라는 두 가지 객체 소멸자를 제공한다.

- finalizer는 예측할 수 없고, 상황에 따라 위험할 수 있어 일반적으로 불필요하다. (deprecated)

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

 

finalizer와 cleaner를 쓰지 않아야 할 구체적인 이유

  • finalizer와 cleaner는 즉시 수행된다는 보장이 없다. 그래서 제때 실행되어야 하는 작업은 절대 할 수 없다.
  • 자바 언어 명세는 어떤 스레드가 finalizer를 수행할지 명시하지 않았으니, 이 문제를 예방할 보편적인 해법은 finalizer를 사용하지 않는 방법뿐이다.
  • cleaner는 자신을 수행할 스레드를 제어할 수 있다는 면에서 조금 낫지만 여전히 백그라운드에서 수행되며 가비지 컬렉터의 통제하에 있으니 즉각 수행되리라는 보장은 없다.
  • 게다가 수행 여부조차 보장하지 않는다. 그래서 상태를 영구적으로 수정하는 작업에서는 절대 finalizer나 clenaer에 의존해서는 안 된다.
  • 심각한 성능 문제도 동반한다.
  • finalizer는 finalizer 공격에 노출되어 심각한 보안 문제를 일으킬 수도 있다.
더보기

Java에서는 객체가 더 이상 참조되지 않을 때 가비지 컬렉션에 의해 소멸된다. 
그리고 객체가 소멸되기 전에 해당 객체의 finalize() 메서드가 호출된다. 

finalize() 메서드는 객체가 소멸되기 직전에 수행할 작업을 정의할 수 있다.
Finalizer 공격은 이러한 finalize() 메서드를 악용하여 악의적인 코드를 실행하려는 시도를 나타낸다. 
공격자는 finalize 메서드를 재정의하여 악성 코드를 포함시키고, 목표 객체가 소멸될 때 이 코드가 실행되도록 설계한다.

 

대안

  • AutoCloseable을 구현해주고, 클라이언트에서 인스턴스를 다 쓰고 나면 close 메서드를 호출하면 된다.