<aside> 💡
자바에서 객체소멸은 가비지컬렉터가 담당하고, 비메모리자원회수는 try-with-resources, try-finally로 해결
</aside>
즉시 수행된다는 보장이 없어!
자원 회수가 제멋대로 지연…
수행 여부조차 보장되지 않음!
System.gc
나 System.runFinalization
메서드는 실행 가능성을 높여줄 순 있으나, 보장하진 않음System.runFinalizersOnExit
와 Runtime.runFinalizersOnExit
는 보장해주긴 하지만, 다른 스레드가 소멸대상의 객체에 접근하고 있어도 실행해 버린다는 매우 치명적인 결함이 있음동작 중 발생한 예외가 무시
GC 의 효율을 떨어뜨림
보안 문제를 일으킬 수 있음
<aside> 💡
객체가 정상적으로 생성되지 않거나 역직렬화 과정에서 예외가 발생한 후에도 finalize()
메서드가 호출되는 상황과 관련된 문제
</aside>
<aside> 💡
파일이나 스레드 등 종료해야 할 자원을 담고 있는 객체의 클래스에서 AutoCloseable
을 구현해주고, 클라이언트에서 인스턴스를 다 쓰고 나면 close
메서드를 호출
</aside>
close
메서드 호출 여부를 필드로 저장close
메서드에서 이 객체는 더 이상 유효하지 않음을 필드에 기록하고, 다른 메서드는 이 필드를 검사해서 객체가 닫힌 후에 불렸다면 IllegalStateException
을 던지도록 구현public class SampleResource implements AutoCloseable {
@Override
public void close() throws RuntimeException {
System.out.println("close");
}
public void hello() {
System.out.println("hello");
}
}
public class SampleRunner {
public static void main(String[] args) {
try {
SampleResource resource = new SampleResource();
resource.hello(); // 리소스 사용
} finally {
resource.close(); // 리소스를 사용하는 쪽에서 쓴 다음 반드시 정리. close() 호출
}
}
}
resource를 쓴 쪽에서 쓴 다음 반드시 close
를 호출하여 리소스를 정리하도록 하자
→ 이를 보장하기 위해(무조건 close
가 호출이 되도록) try-finally block을 사용
public class SampleResource implements AutoCloseable {
@Override
public void close() throws RuntimeException {
System.out.println("close");
}
public void hello() {
System.out.println("hello");
}
}
public class SampleRunner {
public static void main(String[] args) {
try (SampleResource resource = new SampleResource()) {
resource.hello(); // 리소스 사용
}
}
}