GC는 메모리가 부족할 때(쯤) 실행된다.

실행되면, 안 쓰이는 객체들의 Finalization을 실행. 이것이 바로 nondeterministic finalization.
그래서 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);
            }
        }
    }

댓글

이 블로그의 인기 게시물

Oracle NLS_DATE_FORMAT 변경

Stop console process using Ctrl+C.

Alternative to IValueConvert, QuickConverter