Почему мы не освобождаем неуправляемые ресурсы в деструкторе?

Согласно этой статье, http://msdn.microsoft.com/en-us/library/ms177197.aspx в MSDN, мы должны освободить неуправляемые ресурсы в финализаторе и управляемые ресурсы в деструкторе. т.е. следующий шаблон:

// destructors_finalizers_1.cpp
// compile with: /clr /c
ref struct A {
   // destructor cleans up all resources
   ~A() {
      // clean up code to release managed resource
      // ...
      // to avoid code duplication 
      // call finalizer to release unmanaged resources
      this->!A();
   }

   // finalizer cleans up unmanaged resources
   // destructor or garbage collector will
   // clean up managed resources
   !A() {
      // clean up code to release unmanaged resource
      // ...
   }
};

Почему бы просто не поместить все это в деструктор и не выбросить финализатор? Это потому, что существует вероятность того, что объект все еще может быть неопределенно очищен сборщиком мусора?


person Seth    schedule 22.08.2011    source источник


Ответы (1)


Потому что, если вы пропустите вызов деструктора (например, не используя RAII), ваши неуправляемые ресурсы будут утекать, и среда выполнения .NET ничего не сможет с ними поделать.

Если вы очистите свои неуправляемые ресурсы в финализаторе, то среда выполнения будет запускать это, даже если вы испортите свой код и позволите ссылке на ваш объект куда-то улететь :)

По сути, если ваш код содержит ошибки, вы не можете рассчитывать на вызов деструктора, но финализатор всегда будет вызываться, когда объект утилизируется сборщиком мусора.

person porges    schedule 22.08.2011
comment
тогда среда выполнения будет выполнять это, даже если вы испортите свой код и позволите ссылке на ваш объект куда-то улететь Обратите внимание, что это не гарантировано, а скорее всего. - person ildjarn; 22.08.2011
comment
Ага. Всегда помните, что "нулевой сборщик мусора" является корректной реализацией. (У NGC бесконечная память, и он никогда ничего не восстанавливает.) - person porges; 23.08.2011