1 / 14

Жизненный цикл объекта

Жизненный цикл объекта. Создание объекта при вызове оператора new Под объект выделяется область памяти из управляемой кучи . Область памяти инициализируется при работе конструктора. Возможно захватывается ресурс, например, открывается файл или устанавливается соединение с базой данных.

mahdis
Download Presentation

Жизненный цикл объекта

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Жизненный цикл объекта • Создание объекта при вызове оператора new • Под объект выделяется область памяти из управляемой кучи. • Область памяти инициализируется при работе конструктора. • Возможно захватывается ресурс, например, открывается файл или устанавливается соединение с базой данных. • Использование объекта • Вызываются методы объекта, производится доступ к полям данных объекта. • Уничтожение объекта (точное время неопределено) • При помощи деструктора (финализатора) объект превращается в область памяти. • Область памяти возвращается системе. • Освобождением занятых ресурсов занимается сборщик мусора.

  2. Деструктор • В классе можно определить деструктор. • В отличие от C++ порядок вызова деструкторов в C# неопределен. Перед освобождением памяти сборщик мусора вызывает деструктор, но возможны ситуации, когда деструктор для объекта не вызывается совсем. • Определять свои деструкторы нужно только в случае крайней необходимости - они создают значительную нагрузку на систему. • На самом деле наличие в классе деструктора означает неявное переопределение метода Finalize class T { ~T() { Console.WriteLine(“T destructed”); } } class T { protected override void Finalize(){ try {Console.WriteLine(“T destructed”);} finally { base.Finalize();} } }

  3. Сборщик мусора ( Garbage Collector) • CLR использует модель сборки с поколениями 0 – (128-256-512 K) – динамически настраивается 1 – (2Mб) 2 – (10 Mб) • Сборщик мусора начинает работу, когда заполнено поколение 0, неиспользуемые объекты освобождаются, а все остальные перемещаются в поколение 1. • Для больших объектов (> 85000 байт) своя куча и свой алгоритм работы GC. Массивные объекты сборщик мусора не перемещает. • Алгоритмы сборки отличаются в debug и release версиях и в различных версиях OC. Информация: 1. Рихтер Дж. CLR via C#. Программирование на платформе Microsoft .NET Framework 2.0 на языке C#. -Изд. Microsoft Press. Русская редакция, 2007. 2. МаониСтивенс (MaoniStephens).Представляем кучу для массивных объектов - MsDN Magazine ,июнь 2008.

  4. Сборка мусора для объектов с завершением • Перед вызовом Ctor объекты с завершением (с Dtor)заносятся в специальный список объектов, для которых надо вызвать Dtor перед освобождением памяти. • При сборке мусора в поколении 0 объекты с завершением не уничтожаются, а заносятся в специальную очередь завершения. Очередь завершения обрабатывает специальный высокоприоритетный поток. В каком случае Dtor может бытьне выполнен? • После завершения работы приложения CLR вызывает Finalize() для каждого объекта с завершением, но если время возврата из него более 2 сек, CLR завершает процесс и остальные методы Finalize() не вызываются.

  5. Исключения • В коде, использующем библиотеки классов, обработка ошибок во время выполнения программы должна быть разделена на две части : • генерация сообщения об ошибке, которая не может быть обработана локально; • обработка ошибки в том месте, где достаточно информации для анализа нестандартной ситуации и ее обработки. • Механизм исключений C# дает возможность писать устойчивый и простой в сопровождении код. • Можно передать произвольный объем информации в точку обработки ошибки.

  6. Исключенияв C# и C++ • Механизм исключений в C# почти полностью совпадает с механизмом исключений в C++. Отличия: • все исключения C# должны быть экземплярами классов, производных от класса System.Exception; • в C# можно использовать блок finally, который выполняется в любом случае, независимо от того, брошено исключение или нет; • в C# для системных исключений (переполнение, деление на нуль или нулевая ссылка) также определены классы, которые обрабатываются наравне с исключениями уровня приложения. • Исключение явно порождается выражением throw throw new FileNotFoundException(“test.dat”);

  7. Тип System.Exception • Все исключения должны иметь тип System.Exception или быть его потомками publicclassException : ISerializable { … publicException(); publicException( stringmessage ); publicException( stringmessage, ExceptioninnerException ); publicvirtualstringMessage {get;} publicExceptionInnerException {get;} // предыдущее исключение, // если данное было сгенерировано при // обработке предыдущего. public virtual string StackTrace { get;} // строка с именами // и сигнатурами последовательных вызовов, // которые привели к генерации исключения. }

  8. Иерархия классов-исключений ( часть классов) System.ObjectSystem.ExceptionSystem.SystemExceptionSystem.ArgumentExceptionSystem.ArithmeticExceptionSystem.ArrayTypeMismatchExceptionSystem.BadImageFormatExceptionSystem.FormatExceptionSystem.IndexOutOfRangeExceptionSystem.InvalidCastExceptionSystem.NullReferenceException System.OutOfMemoryException System.ExecutionEngineException System.StackOverflowException ... System.ObjectSystem.ExceptionSystem.SystemExceptionSystem.IO.IOExceptionSystem.IO.DirectoryNotFoundExceptionSystem.IO.EndOfStreamExceptionSystem.IO.FileLoadExceptionSystem.IO.FileNotFoundExceptionSystem.IO.PathTooLongException

  9. Блок finally • Выполняется в любом случае, независимо от того, брошено исключение или нет. • Если нет исключения, выполняются все операторы в блоке try, а затем операторы блока finally. • Если брошено исключение, CLR просматривает стек вызовов в поиске обработчика с нужным типом фильтра, и выполняет • сначалаблок finally в тех методах, где нетобработчика с требуемым фильтром • затем блок catch • затем finally из блока try с обработчиком • Допустимые конфигурации • try – catch –finally • try – catch • try – finally

  10. Порядок обработки исключений static void Main ( string[] args) {… код C# … Abc abc = new Abc(); try { abc.Method1(); … код C# … 1 } сatch(Exception1 ex) { … 1 обработка исключений класса … Exception1 и его потомков } catch (Exception2 ex) { … 2 обработка исключений класса … Exception2 и его потомков } finally { … 1 … } } partial class Abc { public void Method1() { … код C# try { … код C# … 2 Method2(); … код C# … 3 } catch (Exception3 ex) { … 3 обработка исключений класса … Exception3 и его потомков } finally { … 2 …} … код C# … 4 } partial class Abc { public void Method2() { … код C# try { … код C# … 5 if( < условие>) throw new ExceptionN(); … код C# … 6 } сatch(Exception1 ex) { … 4 обработка исключений класса … Exception1 и его потомков } catch (Exception4 ex) { … 5 обработка исключений класса … Exception4 и его потомков } finally { … 3 … } … код C# … 7 } <условие>== false код 2 код 5 код 6 finally3 код 7 код 3finally 2 код 4 код 1 finally1 <условие>== true throw Exception1 код 2 код 5 catch4 finally3 код 7 код 3finally 2 код 4 код 1 finally1 <условие>== true throw Exception3 код 2 код 5 finally3 catch 3finally 2 код 4 код 1 finally1 <условие>== true throw Exception2 код 2 код 5 finally3 finally 2 catch2 finally1

  11. Задача освобожденияресурсов. Решение в C++ void main () { try { ... код С++ f(); ... код С++ } catch (exception ex) { ... код С++ } } void f() { Resource R (); // R.Lock(); Lock_Resource LR(R); fInner(R); // R.Unlock(); } void fInner (Resource& rc) { ... код бросает исключение } class Resource { public: void Lock() { ... захват ресурса} void Unlock() { ... освобождение ресурса} Resource () {...} private: ... данные }; class Lock_Resource { public: Lock_Resource (Resource &rci) { rc = rci; rc.Lock();} ~Lock_Resource() { rc.Unlock();} private: Resource& rc; };

  12. Задача освобожденияресурсов. Решение в C#. public static void Main ( string[] args) { try { ... код С# f(); ... код С# } catch (exception ex) { ... код С# } } public void f() { Resource R (); R.Lock(); try { fInner(R);} finally { R.Unlock();} } void fInner (Resource& rc) { ... код бросает исключение } class Resource { public void Lock() { ... захват ресурса} public void Unlock() { ... освобождение ресурса} public Resource () {...} private: ... данные }

  13. Типы с явным освобождением ресурсов • В типах, которые поддерживают модель детерминированного освобождения ресурсов, следует реализовать метод void Dispose(); в котором размещают код, освобождающий ресурсы. • Оператор using - краткая форма try-finally class A : IDisposable { } class B : IDisposable { } using(a = new A()) using(b = new B()) { // … } a = new A(); try { b = new B(); try { … } finally { b.Dispose(); } } finally { a.Dispose(); }

  14. Пример реализации метода Dispose() public class MyResource: IDisposable { private IntPtr handle; // unmanaged resource private Component component = new Component(); // managed resource private bool disposed = false; public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } private void Dispose(bool disposing) { // disposing == true явный вызов из Dispose() // disposing == false вызов из деструктора if ( !this.disposed ) { if ( disposing ) // явный вызов Dispose() {component.Dispose(); // Dispose managed resources. } CloseHandle(handle);// Clean up unmanaged resources } disposed = true; } ~MyResource() { Dispose(false); } }

More Related