JAVA/Effective Java

객체의 생성과 삭제 - 규칙 7 종료자 사용을 피하라

반응형

일반적으로 자주 사용하는 finalizer 예측 불가능하며대체로 위험하고불필요하다.
 
그렇기에  필요로 하는 작업을 명시할 때에는사용해서는 안 된다.
 
문제 사항 1.
 
final 문장에서 Exception 발생하였을 경우에 하단에 기재한 
 
문장이 실행되지 않아 결국 문제를 유발할 수도 있다.



1
2
3
4
5
6
7
8
9
try {
  file = new FileWriter(new File("/test/tt"));
catch (IOException ex) {
  System.out.println("catch block");
finally {
  System.out.println(12/0);  // 강제로 Exception을 발생시킨다. 하단에 file.close() 문장은 실행되지 않는다.
  file.close();
  System.out.println("final block");
}
cs




 문제 사항 2.
 
 
Finalizer 사용하면 프로그램 성능이 심각하게 떨어진다.
 
 finalizer 성능 저하를 발생시키는 이유
1. finalizer 구현하면, GC 자신이 관리하는 finalizer 큐에 저장한다.
2. GC에서 사용하는 특정 쓰레드가 finalizer 큐를 읽고해제해도 되는지 검사한다.
3. 검사  해제 되도 된다면그때서야 해제한다.
 
 3번이 될 때까지 아직도 해제하지 않고 있는 것과검사하는 것에 에너지를 사용하기 때문에 성능에 나쁘다.

출처: <http://ikpil.com/1190>





그럼 반환하거나 삭제해야 하는 자원을 포함하는 객체의 클래스 작성은 어떻게 해야 할까?
 
이는 명시적인 종료 메서드를 하나 정의하여 사용하는 방법이 있다.
 
해당 객체가 주기적으로 해제가 되었는지 여부를 확인하기 위해 해당 객체 안에 그를 체크할  있는 
 
Private 변수를 정의해 두고주기적인 체크를 통해 해제가 되지 않았을 시에 이를 해제해 주어야 한다.
 
 
 
그럼 finalizer try-with-resources 문장이 나온 이후로 진짜로 필요가 없어졌는가?
 
자바가 다른 언어로 만들어진 어플리케이션과 상호 작용할 수 있는 인터페이스 JNI 같이
 
다른언어에서 작성된 메소드등을 수행하는 객체를 네이티브 객체라고 한다
 
Ex) 
CallAgent ca = new Ca(); // 네이티브 객체
Ca.execte();
 
이런 객체는 일반적인 객체가 아니므로 가비지 콜렉터가 이에 대한 리소스 반환을  수가 없다
 
그래서 이런 경우에는 finalizer 사용하여 네이티브 객체를 반환한다.
 
 
finalizer 구현  주의사항
 
 
부모 클래스에 finalizer 함수를 구현해 놓고 하위 클래스에서 finalizer  정의  경우에는 
 
다음과 같이 진행 해야 한다.
 


1
2
3
4
5
6
7
8
@Override
protected void finalize() throws Throwable {
try {
  // 하위 클래스 리소스 제거 부분 기입
finally {
  Super.finalize(); // 부모 클래스 리소스 해제 부분 메소드 호출
}
}
cs



렇게 기입을 해주어야 하위클래스 finalize 메소드가 실행되는 과정에 예외가 발생해도 상위클래스 종료자를 해제할  있기 때문이다.
 
 
만약 자식 클래스에서 상위클래스 finalize() 메서드를 해제하지 않을 경우큰문제가 되기 때문에 
 
이를 예방하기 위해서 모든 객체마다 익명클래스를 생성하여 finalize 정의하는 것이다.
 
Finalizer Guardian : 종료 보호자 패턴
 
 익명 클래스는  클래스를 객체로 가지고 있는 클래스의 객체를 종료시키는 역할을 한다.


1
2
3
4
5
6
7
class Foo {
    private final Object finalizerGuardian = new Object() {
        protected void finalize() throws Throwable {
            /* finalize outer Foo object */
        }
    }
}
cs





출처 : 조슈아 블로크, 『 Effective Java 2/E』, 이병준 옮김, 인사이트(2014.9.1), 규칙7 인용.



반응형