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); } } }
댓글
댓글 쓰기