제목 : GC가 작동할때 특정 작업을 할 수 있는지…
글쓴이: 손님(guest) 2004/04/12 22:20:00 조회수:9 줄수:14
안녕하세요.
어떤 객체가 소멸될때, 즉 GC가 작동하여 해당 객체를 소멸시킬때 특정 작업을
수행하고 싶은데 어떻게 구현해야 할까요?
finalize() 메소드는 protected라 override를 할 수는 없고 다른 방법이 있을것
같긴 한데요.
알려주시면 감사하겠습니다.
PC가 많은 사무실은 요즘 엄청 덥죠? ^^; 감기 조심하세요.
제목 : Re: 할수 없는거 같은데요..
글쓴이: 서민구(guest) 2004/04/13 00:15:07 조회수:1 줄수:64
GC라는게 동작한다는 보장도 없고,
언제동작하는지도 모르고 문제가 많죠..
(닷넷이랑 틀릴지 모르지만) 닷넷 쪽의 문서를 보면
상당히 상세한 설명글이 하나 있는데, finalize가 되면서
우리가 작성해 놓은 객체를 다시 살릴(resurrection)수 있습니다.
이렇게되면 finalize했어도 또 살아나죠.
또 누군가 클래스가 finalize를 잘못하면
중간에 무한루프를 돌면서 내 finalize까지 실행기회가 안올 수도 있고요.
그리고 protected이기에 override할 수 있습니다.
단 문제는 내 클래스를 누군가가 상속받았다면
finalize끝에서 super.finalize를 불러주어야 하는데, 그걸 잊어버리면
부모 클래스가 finalize되지 않는 문제가 생기고요.
이 문제를 해결하는 방법이 finalize guardian이라는 이디엄인데,
class Foo { private final Object finalizerGuardian = new Object() { protected void finalize() throws Throwable { /* finalize outer Foo object */ } } }
이와같이 작성하는거죠. 그러면 자식 클래스가 finalize를 부르는가에
무관하게 finalize가 되는거거든요.
그러나 앞서 말씀드린바와같이 GC의 동작시점과 동작여부는 늘 보장불가능한
것이므로.. 가능하면 Dispose 를 사용하는게 좋습니다. 대략 다음과 같은 식인데요.
public interface IDisposable { public void dispose(); } public class Test implements IDisposable { public void dispose() { ... // 처리 작업 } }
이제 Test를 가져다 쓰는 클래스는
Test test = new Test(); ... // 작업 if (test instanceof IDisposable) { ((IDisposable) test).dispose(); }
이런식으로 처리하면 됩니다.
instanceof를 쓰는건 Test와 다른 객체들이 컬렉션에 혼합되어
들어있을 때를 위한 예시구요..
가만히 생각해보시면 AWT에서 window없앨 때 dispose() 메소드를
사용하는걸 아실겁니다. 왜 그런지 잘 생각해보세요.
마찬가지로 Connection역시 (물론 finalize에서도 처리하겠지만) 명시적으로
close()를 호출하여 닫습니다.
이처럼, ‘메모리’는 JVM에게 맡기고 ‘그외의 비 관리 자원(unmanaged resource)’의
모든 처리는 프로그래머가 직접해주어야합니다… 특히나 unmanaged resouce들은
비용이 하나같이 높아서, 사실상 이처럼 사용이 끝나면 직접적으로 닫는게
중요하므로 GC에게 맡겨놓고 잊어버린다거나 하는건 문제가 됩니다..
source: http://tinyurl.com/2m25a