Чи підрахунок посилань на GC проти трасування GC є властивістю мови чи властивістю реалізації?


9

Ми іноді чуємо, що "Свіфт не робить класичну (трасування) GC, вона використовує ARC".

Але я не впевнений, чи є щось у семантиці Свіфта, що вимагає підрахунку посилань. Здається, що можна створити власний компілятор Swift і час виконання, щоб використовувати трасування GC.

Отже, що саме "рахується" про Свіфта? Реалізація Apple чи сама мова? Чи є частини мови чи бібліотека, які так сильно підтримують ARC, що ми можемо використовувати цю мітку для самої мови?

Відповіді:


9

Швидкий гарантує, що після останнього посилання на об'єкт відкидається, об'єкт дезініціалізується, і deinitкод негайно запускається.

Отримання такого роду гарантії через GC неможливо - принаймні, не без шкоди для виконання. Стандартні механізми GC забезпечують лише те, що deinitв кінці кінців буде запущений код, наприклад, на наступному циклі GC. Для точної семантики десь потрібен довідковий підрахунок.


3
Так, присутність deinitяк ключового слова, так і пов'язаної з ним семантики - це справді те, що в мові прямо підраховує посилання, а не сферу реалізації.
Рей Тол

2
Ніщо не заважає GCed виконувати час перевірки недоступних об'єктів, коли щось розміщується. Це просто жахливо неефективно.
Рафаель

@Raphael Відредаговано, щоб бути точнішим з цього приводу.
чі

3

Чі відповів на конкретне запитання в тілі про швидку, ця відповідь відповідає на більш загальне запитання в заголовку.

Чи підрахунок посилань на GC проти трасування GC є властивістю мови чи властивістю реалізації?

підрахунок посилань GC і відстеження GC забезпечують програміста різні гарантії.

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

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


4
Також можливо поєднувати знижки зі знижкою та GC. Тоді мова може задокументувати, що об’єкти виконують свій деструктор, як тільки вони не відносяться (маючи на увазі перерахунок у тій чи іншій формі), і що еталонні цикли в кінці кінців будуть знищені (маючи на увазі певну форму GC). Крім того, реалізація може це зробити, поки мова не гарантує, коли запускаються деструктори (IIRC - це справа Python та його посилання на реалізацію), у цьому випадку це буде властивістю реалізації.
Жил "ТАК - перестань бути злим"

1

Ви можете взяти мову, відому як Swift, і перейменувати її на "Swift with ARC". Потім можна створити нову мову під назвою "Swift with GC" з точно таким же синтаксисом, але з меншими гарантіями щодо розміщення об'єктів.

У Swift з ARC, як тільки число посилань дорівнює 0, об'єкт піде. Під час збору сміття, якщо у вас слабке посилання, ви можете призначити це слабке посилання сильним посиланням на "відновлення" об'єкта. (У Swift, коли кількість посилань дорівнює 0, слабкі посилання нульові); це головна різниця.

І звичайно, Свіфт з ARC гарантує, що вбивство останнього опорного підрахунку негайно розселить об'єкт. Наприклад, у вас може бути клас FileWriter, коли вам заборонено одночасно існувати два екземпляри запису в один і той же файл. У Swift з ARC можна було б сказати oldWriter = nil; newWriter = FileWriter (...), і ви знаєте, що новий FileWriter створюється лише після видалення старого (якщо ви не зберегли іншого посилання навколо); в Swift з GC це не працює.

Інша відмінність полягає в тому, що в "Швидкому переході з ARC" об'єкти, на які посилаються лише сильні еталонні цикли, але фактично не доступні, гарантовано не будуть розміщені.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.