KeyWord
IDisposable , 명시적 자원해제, using 블럭, GC 의 수집기능 보완
앞서 객체의 소멸자에 대해 알아본 적이 있다.
일단 다음의 링크에서 확인해 보자
--> 소멸자
소멸자는 객체가 더 이상 참조당하지 않는 1차적은 조건을 만족하면 GC(가비지컬렉터)에 의해서 호출된다
GC에서 맡겨진 이러한 매커니즘의 한가지 단점은 정확히 객체가 해제 되는 시점을 알수 없다는 것이다.
즉, 객체가 더 이상 참조당하지 않는다고 해도 그 즉시 소멸자가 호출되는것은 아니라는 말이다.
만일 객체가 시스템의 중요한 자원을 사용하거나 반납이 빠를 수록 좋은 자원을 사용한다면 이러한 자원에 대한 해제를 소멸자에게 맡기는건 그리 좋지 않다는 말이된다.
이때 사용할 수 있는 것이 바로 Dispose 메서드 이다.
프로그래머는 객체가 GC에 의해 소멸되기 이전에
객체가 사용하는 중요한 시스템 자원에 대한 해제를 보다 빨리, 그리고 명시적으로 해제 할 수 있다.
닷넷 프레임워크는 이러한 메커니즘을 위해 IDisposable 인터페이스를 제공한다.
이 인터페이스를 구현하는 클래스는 Dispose 메서드를 재정의 해야 하는데 이 메서드가 바로 자원의 해제를 담당하는 메서드가 된다. (즉 프로그래머는 Dispose 메서드에 자원을 해제하는 코드를 포함하면 된다)
단, 이 메서드는 소멸자 처럼 GC에 의해 자동으로 호출되는 것이 아니라 명시적으로 호출 해 줘야 한다.
A a = new A();
// .....a 객체를 사용.....
a.Dispose();
닷넷 프레임웍은 Dispose 를 명시적으로 호출하지 않아도 자동으로 호출해 주는 구조를 지원하는데
바로 using 키워드 이다.
using(A a = new A()){
//...a 객체 사용...
}
using 블록을 벗어날려는 시점에 a 의 Dispose 는 자동으로 호출된다.
(당연하겠지만 Dispose 가 호출되었다고 해서 그 객체가 소멸된 것은 아니다.)
닷넷에서는 IDisposable 를 구현하는 많은 클래스 들이 있다.
Brush, Pen 과 같은 그래픽 관련 클래스를 대표적으로 예를 들 수 있겠다.
- 샘플 Code -
class Test
{
public void t()
{
using(A a = new A())
{
//객체 a 로 작업처리를 한다
//이 블럭을 빠져 나가는 시점에 a 의 Dispose 가 호출된다
} }
}
class A : IDisposable
{
public void Dispose()
{
Console.WriteLine("Dispose 호출됨");
}
~ A()
{
Console.WriteLine("소멸자 호출됨");
}
} |
다음은 msdn 에 설명된 IDisposable 에 대한 설명이다
IDisposable 인터페이스 클래스 인스턴스는 주로 Windows 핸들 및 데이터베이스 연결과 같이 CLR에서 관리하지 않는 리소스를 제어합니다. 가비지 수집 기능을 보완하기 위해 클래스에서는 IDisposable 인터페이스를 구현하는 경우 시스템 리소스를 능동적으로 관리하기 위한 메커니즘을 제공할 수 있습니다. IDisposable에는 개체 사용이 끝났을 때 클라이언트에서 호출해야 하는 Dispose 메서드가 포함되어 있습니다. Dispose를 구현하면 리소스를 해제하고 파일 닫기 및 데이터베이스 연결 끊기 등과 같은 작업을 수행할 수 있습니다. Finalize 소멸자와 달리 Dispose 메서드는 자동으로 호출되지 않습니다. 리소스를 해제하려면 클래스의 클라이언트에서 Dispose를 명시적으로 호출해야 합니다. |