우아한테크코스/공부

finalizer와 cleaner 사용을 피하라

자바지기 2022. 3. 22. 09:40
반응형

finalizer와 cleaner 사용을 피하라

자바의 객체 소멸자

1. finalizer (자바 8까지)

예측 불가능하고, 상황에 따라 위험할 수도 있어 일반적으로 불필요

2. cleaner (자바 9~)

finalizer보다는 덜 위험하지만 마찬가지로 예측 불가능, 느림, 일반적으로 불필요하다.

 

어째서 불필요한지?

1. finalizer와 cleaner는 즉시 수행된다는 보장이 없다.

즉, 두 가지로는 제때 실행되어야 하는 작업은 절대할 수 없다.

ex)

파일 닫기의 경우, 동시에 열 수 있는 파일 개수에 한계가 있기 때문에,
finalizer나 cleaner가 제 때 실행되지 않는다면, 새로운 파일을 열지 못하게 될 수 있다.

2. 수행 여부를 보장하지 않는다.

접근할 수 없는 일부 객체에 딸린 종료 작업을 전혀 수행하지 못한 채 프로그램이 중단될 수 있다.

3. finalizer 동작 중 발생한 예외는 무시되며, 처리할 작업이 남았더라도 그 순간 종료된다.

4. 성능이 안좋다.

ex)

AutoCloseable 객체를 가비지 컬렉터가 수거하는 시간 : 12ns

finalizer : 550ns

 

대체 방안

AutoCloseable을 구현하고 인스턴스를 다 쓰면 close 메소드를 호출한다.

close 메소드에는 객체가 더 이상 유효하지 않음을 필드에 기록하고,
다른 메서드는 이 필드를 검사해서 객체가 닫힌 후에 불렸다면,
IllegalStateException을 던진다.

 

그렇다면 finalize와 cleaner는 어디에 쓰이는가 ?

  1. 자원의 소유자가 close 메서드를 호출하지 않는 것에 대비한 안전망 역할
    즉, 어찌되건 자원 화수를 해주기 때문에 아예 안하는 것보단 낫다.
  2. 네이티브 피어와 연결된 객체

네이티브 피어란?

일반 자바 객체가 네이티브 메서드를 통해 기능을 위임한 네이티브 객체.

네이티브 메서드는 Java 이외의 언어로 만들어진 어플리케이션이나 라이브러리가 상호작용할 수 있도록 연결시켜주는 인터페이스이다.

쉽게 말해, 다른 언어와 연결해주는 객체

네이티브 피어는 자바 객체가 아니라서 가비지 컬렉터로 처리할 수 없다.
따라서 cleaner나 finalizer가 처리하기 적당한 작업이다.

단, 성능 저하를 감당할 수 있고 네이티브 피어가 심각한 자원을 가지고 있지 않을 때 사용 가능

(아이템 66. 네이티브 메서드는 신중히 사용하라 -> 네이티브 메서드 성능 구림)

반응형