GC는 메모리가 부족할 때(쯤) 실행된다.
실행되면, 안 쓰이는 객체들의 Finalization을 실행. 이것이 바로 nondeterministic finalization.
그래서 IDisposable을 통해서 명시적으로 정리작업을 해야 한다. 또한 IDisposable.Dispose()는 여러 번 호출되도 문제가 되지 않아야 하므로, 내부적으로 정리 작업이 실행됐는 지에 대한 상태값을 가지고 있어야 한다.
The following list summarizes the resource management rules and concepts:
그래서 IDisposable을 통해서 명시적으로 정리작업을 해야 한다. 또한 IDisposable.Dispose()는 여러 번 호출되도 문제가 되지 않아야 하므로, 내부적으로 정리 작업이 실행됐는 지에 대한 상태값을 가지고 있어야 한다.
The following list summarizes the resource management rules and concepts:
- If a class contains no managed resources and no unmanaged resources, it doesn’t need to implement IDisposableor have a destructor.
- If the class has only managed resources, it should implement IDisposablebut it doesn’t need a destructor. (When the destructor executes, you can’t be sure managed objects still exist, so you can’t call their Disposemethods anyway.)
- If the class has only unmanaged resources, it needs to implement IDisposableand needs a destructor in case the program doesn’t call Dispose.
- The Disposemethod must be safe to run more than once. You can achieve that by using a variable to keep track of whether it has been run before.
- The Disposemethod should free both managed and unmanaged resources.
- The destructor should free only unmanaged resources. (When the destructor executes, you can’t be sure managed objects still exist, so you can’t call their Disposemethods anyway.)
- After freeing resources, the destructor should call GC.SuppressFinalize, so the object can skip the finalization queue.
class DisposableClass : IDisposable
{
// A name to keep track of the object.
public string Name = "";
// Free managed and unmanaged resources.
public void Dispose()
{
FreeResources(true);
}
// Destructor to clean up unmanaged resources
// but not managed resources.
~DisposableClass()
{
FreeResources(false);
}
// Keep track if whether resources are already freed.
private bool ResourcesAreFreed = false;
// Free resources.
private void FreeResources(bool freeManagedResources)
{
Console.WriteLine(Name + ": FreeResources");
if (!ResourcesAreFreed)
{
// Dispose of managed resources if appropriate.
if (freeManagedResources)
{
// Dispose of managed resources here.
Console.WriteLine(Name + ": Dispose of managed resources");
}
// Dispose of unmanaged resources here.
Console.WriteLine(Name + ": Dispose of unmanaged resources");
// Remember that we have disposed of resources.
ResourcesAreFreed = true;
// We don't need the destructor because
// our resources are already freed.
GC.SuppressFinalize(this);
}
}
}
댓글
댓글 쓰기