본문 바로가기

책, 강의 정리/이펙티브자바

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

자바의 객체 소멸자: finalizer(자바 9 부터 deprecated), cleaner(자바 9)  

 

 

사용하지 말아야 할 이유

 

1. 사용시기, 사용유무 모두 불확실하고 느리다.

   System.gc, System.runFinalization 으로 GC 실행의 가능성을 높여줄 수 는 있지만 보장하진 않는다.

 

2. System,.runFinalizersOnExit, Runtime.runFinalizersOnExit 은 finalizer 실행을 보장하지만 "쓰레드가 멈출 수 있다"는 치명적인 단점이 있다.

 

3. finalizer 동작 중 예외가 발생하면 마무리가 덜 된 상태로 종료될 수 있다.

 

4. finalizer 공격에 노출될 수 있다. 

-  A 를 상속받는 B 클래스의 생성자 또는 직렬화 과정에서 exception 을 던지게하고 악의적인 행위를 하는 finalizer 메서드를 구현해놓는다고 하면, B 생성 시 exception 이 발생하면 finalizer 가 수행되고 오버라이드된 악의적인 로직을 수행한다. 이 finalizer 를 참조하는 정적 필드를 만들면서 gc 대상이 되지 못하도록 할 수도 있다. 

 

해결방법: Final 클래스를 만들어 상속이 불가하게하거나 아무것도 하지 않는 finalize 메서드를 오버라이딩하고 final 키워드를 사용하여 상속되지 않도록 한다. 

 

 

올바른 자원 회수 방법

 

1. AutoCloseable 인터페이스 구현 

- close() 메서드

- try-with-resources 

- try 블록이 끝날 때 close 를 호출해줌. . 

 

 

finalizer 와 cleaner 를 사용해야하는 시기

 

1. try - with - resources 를 사용하지 않을 시를 대비하여 "안전망" 정도로

 

2. 중요한 리소스가 아닌 네이티브 피어와 연결된 객체. (try-with-resources 를 더 권장)