- 자바는 finalizer와 cleaner라는 두 가지 객체 소멸자를 제공한다.
- finalizer는 예측할 수 없고, 상황에 따라 위험할 수 있어 일반적으로 불필요하다. (deprecated)
- cleaner는 그 대안으로 소개되었지만 여전히 예측할 수 없고 느리고 일반적으로 불필요하다.
finalizer와 cleaner를 쓰지 않아야 할 구체적인 이유
- finalizer와 cleaner는 즉시 수행된다는 보장이 없다. 그래서 제때 실행되어야 하는 작업은 절대 할 수 없다.
- 자바 언어 명세는 어떤 스레드가 finalizer를 수행할지 명시하지 않았으니, 이 문제를 예방할 보편적인 해법은 finalizer를 사용하지 않는 방법뿐이다.
- cleaner는 자신을 수행할 스레드를 제어할 수 있다는 면에서 조금 낫지만 여전히 백그라운드에서 수행되며 가비지 컬렉터의 통제하에 있으니 즉각 수행되리라는 보장은 없다.
- 게다가 수행 여부조차 보장하지 않는다. 그래서 상태를 영구적으로 수정하는 작업에서는 절대 finalizer나 clenaer에 의존해서는 안 된다.
- 심각한 성능 문제도 동반한다.
- finalizer는 finalizer 공격에 노출되어 심각한 보안 문제를 일으킬 수도 있다.
더보기
Java에서는 객체가 더 이상 참조되지 않을 때 가비지 컬렉션에 의해 소멸된다.
그리고 객체가 소멸되기 전에 해당 객체의 finalize() 메서드가 호출된다.
finalize() 메서드는 객체가 소멸되기 직전에 수행할 작업을 정의할 수 있다.
Finalizer 공격은 이러한 finalize() 메서드를 악용하여 악의적인 코드를 실행하려는 시도를 나타낸다.
공격자는 finalize 메서드를 재정의하여 악성 코드를 포함시키고, 목표 객체가 소멸될 때 이 코드가 실행되도록 설계한다.
대안
- AutoCloseable을 구현해주고, 클라이언트에서 인스턴스를 다 쓰고 나면 close 메서드를 호출하면 된다.
'이펙티브 자바 > 2장 객체 생성과 파괴' 카테고리의 다른 글
아이템 9 try-finally 보다는 try-with-resources를 사용하라 (0) | 2023.12.19 |
---|---|
아이템 7 다 쓴 객체 참조를 해제하라 (1) | 2023.12.18 |
아이템 6 불필요한 객체 생성을 피하라 (0) | 2023.12.18 |
아이템 5 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라 (0) | 2023.12.18 |
아이템 4 인스턴스화를 막으려거든 private 생성자를 사용하라 (0) | 2023.12.18 |