Цикл життя об’єкта в .NET

Доброї пори часу, в даній статті я напишу про цикл життя об’єктів в CLR. Ви також зрозумієте як працює Garbage Collector (прибиральник сміття).

Програмісти C# ніколи напряму не оперують життям об’єктів, також в цій мові немає ключового слова delete, яке ви могли бачити в такій мові як С++, замість цього життям об’єктів керує Common Language Runtime. Всі .NET об’єкти (екземпляри класів), які створюються, розміщуються в “керованій купі” (managed heap), де вони всі стають кандидатами на знищення прибиральника сміття.

Створення об’єктів

Для початку нагадаю різницю між класом та об’єктом. Клас – це певна структура, яка описується в .cs файлі, а об’єкт – це екземпляр класу. Тобто ми можемо описати один клас і створити до вільну кількість його екземплярів. При створені екземпляру (за допомогою ключового слова new) ми отримаємо посилання на об’єкт, який насправді розміщений в керованій купі. Ця змінна розміщується в стеку і доки ми на неї маємо посилання, об’єкт не може бути видаленим.

Наприклад:


MyClass obj1 = new MyClass(); //Отримуємо посилання “obj1”
obj1.DoSomething(); //Виконуємо операції над об’єктом використовуючи посилання.
//Тут цей об’єкт стає кандидатом на видалення.

При створенні об’єкту CLR здійснює наступні завдання:

  • Вираховує потрібну кількість пам’яті для розміщення цього об’єкту
  • Перевіряє керовану купу, для того щоб впевнитись чи достатньо місця для розміщення цього об’єкту, викликає його конструктор.
  • Перед тим як повернути посилання на цей об’єкт, він переміщує вказівник на наступний об’єкт, який в майбутньому може бути розміщений в купі

Може виникнути певна ситуація, коли CLR підрахувавши потрібну кількість пам’яті для розміщення визначила, що об’єкт не можна розмістити, так як пам’яті не вистачає. В цьому випадку в дію запускається прибиральник сміття та звільняє пам’ять.

Під час дії збірника сміття, він призупиняє всі виконавчі потоки в даному процесі, для того щоб коректно здійснити очистку, на щастя він є оптимізованим, і ви ніколи не помітите що ваш код призупинив своє виконання.

Видалення об’єктів

Garbage Collector при дослідження керованої кучі беручи інформацію з коренів об’єктів, складає їх граф, для того щоб перевірити їх посилання та взаємозалежності. Якщо певний об’єкт немає посилань і на нього ніхто не посилається то він видаляється з купи і вона пере налаштовується таким чином, щоб посунути всі об’єкти, для того щоб вони були компактно розміщенні один біля одного.

Покоління об’єктів

Для оптимізації процесу збирання сміття, ввели таке поняття як покоління. Насправді кожен об’єкт, який розміщений в купі має позначення, яке ідентифікує його покоління. Чим більше в нього покоління, тим більше він буде жити. Існують такі покоління:

  • Нульове покоління, в яке потрапляють всі створені об’єкти
  • Перше покоління, яким помічають об’єкт при його виживанні після першої збірки сміття.
  • Друге покоління, помічаються всі об’єкти, які пережили більше ніж одне прибирання сміття.

При початку очистки пам’яті, прибиральник сміття дивиться тільки на перше покоління, та якщо після очистки пам’яті йому недостатньо, він рухається досліджувати наступне покоління (1), аналогічно після очистки цього покоління при недостачі пам’яті він перевіряє (2) покоління.

Засоби керування прибиральником в .NET Framework

В просторі імен System є такий тип як GC, який нам дозволяє керувати пам’яттю.

Нижче наведено перелік основних методів, які він нам надає:

Collect() – Заставляє прибиральника виконати очистку сміття.

CollectionCount() – Повертає кількість, яка дає нам знати скільки разів проходила очистка в заданому поколінні.

GetGeneration() – Повертає покоління, до якого належить заданий об’єкт.

GetTotalMemory() – Повертає кількість пам’яті, яка зараз використовується в керованій купі.

MaxGeneration – Повертає максимальне покоління, яке доступне в виконавчій версії .NET

Підсумок

В .NET пам’яттю нам не потрібно маніпулювати вручну, що спрощує створення програм та надає можливість нам більше роздумувати над моделюванням та реалізацією певної функціональності замість обдумування технічних аспектів в коді. Дана стаття має допоможе вам більше орієнтуватись в життєвому циклі об’єктів, та ознайомити вас з засобами для ручного керування прибиральником.

Дуже дякую за увагу J . До зустрічі!

Advertisements

, , , ,

  1. Leave a comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: