Является ли подсчет ссылок GC против трассировки GC свойством языка или свойством реализации?


9

Мы иногда слышим: «Swift не выполняет классическую (отслеживание) GC, он использует ARC».

Но я не уверен, что в семантике Swift есть что-то, что требует подсчета ссылок. Кажется, что можно использовать собственный компилятор Swift и среду выполнения, чтобы использовать трассировку GC.

Так что же такое «счетчик ссылок» в Swift? Реализация Apple или сам язык? Существуют ли части языка или библиотеки, которые так сильно поддерживают ARC, что мы можем использовать этот ярлык для самого языка?

Ответы:


9

Swift гарантирует, что после удаления последней ссылки на объект объект деинициализируется, и deinitкод немедленно запускается.

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


3
Ах, так что присутствие deinitв качестве ключевого слова и связанная с ним семантика действительно являются тем, что делает подсчет ссылок прямо в языке, а не в реализации.
Рэй Тоал

2
Ничто не мешает среде выполнения GCed проверять недоступные объекты всякий раз, когда что-то освобождается. Это просто ужасно неэффективно.
Рафаэль

@Raphael Отредактировано, чтобы быть более точным в этом вопросе.
Чи

3

Чи ответил на конкретный вопрос в теле о swift, этот ответ отвечает на более общий вопрос в заголовке.

Является ли подсчет ссылок GC против трассировки GC свойством языка или свойством реализации?

GC подсчета ссылок и GC трассировки предоставляют программисту различные гарантии.

Подсчет ссылок обеспечивает детерминизм в месте в потоке программы, где объект уничтожается, что может быть важно, если у объекта есть ограниченные ресурсы, которые должны быть быстро освобождены. С другой стороны, он не может справиться с циклами «сильных» ссылок.

Это зависит от спецификации отдельного языка, что, если какие-либо характеристики гарантированы, и, следовательно, какие варианты доступны для совместимой реализации.


4
Также возможно объединить refcount и GC. Затем язык может задокументировать, что деструктор объектов исполняется, как только на них нет ссылок (подразумевается пересчет в той или иной форме), и что циклы ссылок будут в конечном итоге уничтожены (подразумевается некоторая форма GC). Альтернативно, реализация могла бы сделать это, в то время как язык не гарантирует, когда деструкторы будут запущены (IIRC, как в случае с Python и его эталонной реализацией), в этом случае это будет свойство реализации.
Жиль "ТАК - перестань быть злым"

1

Вы можете взять язык, известный как Swift, и переименовать его в «Swift with ARC». Затем вы можете создать новый язык под названием «Swift with GC» с точно таким же синтаксисом, но с меньшим количеством гарантий о том, когда объекты освобождаются.

В Swift с ARC, если счетчик ссылок равен 0, объект будет идти. При сборке мусора, если у вас есть слабая ссылка, вы можете присвоить эту слабую ссылку сильной ссылке, чтобы «восстановить» объект. (В Swift, если число ссылок равно 0, слабые ссылки равны нулю); это серьезная разница.

И, конечно же, Swift с ARC гарантирует, что уничтожение последнего счетчика ссылок немедленно освободит объект. Например, у вас может быть класс FileWriter, в котором вам не разрешено иметь два экземпляра, записывающих в один и тот же файл одновременно. В Swift с ARC вы можете сказать oldWriter = nil; newWriter = FileWriter (...), и вы будете знать, что новый FileWriter создается только после удаления старого (если вы не сохранили другую ссылку); в Swift с GC это не сработает.

Другое отличие состоит в том, что в «Swift with ARC» объекты, на которые ссылаются только через циклы сильных ссылок, но которые на самом деле не достижимы, гарантированно не освобождаются.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.