Jump to content

Подсчет ссылок

В информатике — это метод программирования , подсчет ссылок позволяющий сохранять количество ссылок , указателей или дескрипторов ресурса, например объекта, блока памяти, дискового пространства и других.

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

Преимущества и недостатки

[ редактировать ]

Основное преимущество подсчета ссылок перед отслеживанием сборки мусора заключается в том, что объекты удаляются, как только на них больше нельзя ссылаться, и постепенно, без длительных пауз для циклов сбора и с четко определенным временем жизни каждого объекта. В приложениях реального времени или системах с ограниченной памятью это важно для поддержания оперативности. Подсчет ссылок также является одной из самых простых форм управления памятью. Это также позволяет эффективно управлять ресурсами, не относящимися к памяти, такими как объекты операционной системы, которых часто гораздо меньше, чем памяти (системы трассировки сбора мусора используют финализаторы , для этого [ нужна ссылка ] но отложенное восстановление может вызвать проблемы). Взвешенные счетчики ссылок — хорошее решение для сбора мусора в распределенной системе.

Пример кругового списка из магистерской диссертации 1985 года. [1] Прямоугольники обозначают пары минусов со счетчиком ссылок. Даже если входящий верхний левый указатель будет удален, все счетчики останутся >0.

Циклы трассировки сборки мусора запускаются слишком часто, если набор живых объектов заполняет большую часть доступной памяти; [ нужна ссылка ] для эффективности требуется дополнительное пространство. [ нужна ссылка ] Производительность подсчета ссылок не ухудшается по мере уменьшения общего объема свободного пространства. [2]

Счетчики ссылок также являются полезной информацией, которую можно использовать в качестве входных данных для других оптимизаций во время выполнения. Например, системы, которые сильно зависят от неизменяемых объектов, таких как многие функциональные языки программирования, могут страдать от снижения эффективности из-за частого копирования. [ нужна ссылка ] Однако если компилятор (или система времени выполнения ) знает, что конкретный объект имеет только одну ссылку (как это бывает во многих системах) и что ссылка теряется одновременно с созданием аналогичного нового объекта (как в строке добавить заявление str ← str + "a"), он может заменить операцию мутацией исходного объекта.

Подсчет ссылок в простой форме имеет три основных недостатка по сравнению со сборкой мусора с отслеживанием, оба из которых требуют дополнительных механизмов для улучшения:

  • Частые обновления, которые он предполагает, являются источником неэффективности. Хотя отслеживание сборщиков мусора может серьезно повлиять на эффективность из-за переключения контекста и ошибок в строке кэша, они собирают мусор относительно нечасто, а доступ к объектам осуществляется постоянно. Кроме того, что менее важно, подсчет ссылок требует, чтобы каждый объект, управляемый памятью, зарезервировал место для подсчета ссылок. При трассировке сборщиков мусора эта информация неявно сохраняется в ссылках, которые ссылаются на этот объект, что экономит место, хотя трассировка сборщиков мусора, особенно инкрементных, может потребовать дополнительного места для других целей.
  • Наивный алгоритм, описанный выше, не может справиться ссылочные циклы объект, который прямо или косвенно ссылается на себя. Механизм, полагающийся исключительно на подсчет ссылок, никогда не будет рассматривать циклические цепочки объектов для удаления, поскольку их счетчик ссылок гарантированно останется ненулевым (см. рисунок). Существуют методы решения этой проблемы, но они также могут увеличить накладные расходы и сложность подсчета ссылок — с другой стороны, эти методы необходимо применять только к данным, которые могут образовывать циклы, часто представляющие собой небольшое подмножество всех данных. Одним из таких методов является использование слабых ссылок , а другой предполагает использование алгоритма очистки по меткам , который нечасто вызывается для очистки.
  • В параллельной настройке все обновления счетчиков ссылок и все модификации указателей должны быть атомарными операциями , что влечет за собой дополнительные затраты. Есть три причины для требований атомарности. Во-первых, поле счетчика ссылок может обновляться несколькими потоками, поэтому для обновления счетчиков должна использоваться адекватная атомарная инструкция, такая как (дорогая) операция сравнения и замены. Во-вторых, должно быть ясно, какой объект теряет ссылку, чтобы его счетчик ссылок можно было адекватно уменьшить. Но определение этого объекта является нетривиальной задачей в ситуации, когда несколько потоков пытаются изменить одну и ту же ссылку (т. е. когда возможны гонки данных). Наконец, существует тонкая гонка, в которой один поток получает указатель на объект, но прежде чем он увеличивает счетчик ссылок на объект, все остальные ссылки на этот объект одновременно удаляются другими потоками, и объект восстанавливается, в результате чего указанный поток увеличить счетчик ссылок восстановленного объекта.

В дополнение к этому, если память выделяется из списка свободных, подсчет ссылок страдает от плохой локальности. Сам по себе подсчет ссылок не может перемещать объекты для повышения производительности кэша, поэтому высокопроизводительные сборщики также реализуют отслеживающий сборщик мусора. Большинство реализаций (например, PHP и Objective-C) страдают от низкой производительности кэша, поскольку они не реализуют копирование объектов. [3]

Интерпретация графика

[ редактировать ]

Имея дело со схемами сборки мусора, часто полезно думать о графе ссылок , который представляет собой ориентированный граф которого , вершинами являются объекты, и существует ребро от объекта A к объекту B, если A содержит ссылку на B. Мы также имеют специальную вершину или вершины, представляющие локальные переменные и ссылки, хранящиеся в системе времени выполнения, и никакие ребра никогда не идут к этим узлам, хотя ребра могут идти от них к другим узлам.

В этом контексте простым счетчиком ссылок объекта является входная степень его вершины. Удаление вершины похоже на сбор объекта. Это можно сделать только тогда, когда вершина не имеет входящих ребер, поэтому это не влияет на исходящую степень любых других вершин, но может влиять на входную степень других вершин, вызывая сбор соответствующих им объектов, если их в результате ин-градус также становится равным 0.

Компонент связности, содержащий специальную вершину, содержит объекты, которые невозможно собрать, а остальные компоненты связности графа содержат только мусор. Если реализован алгоритм сборки мусора с подсчетом ссылок, то каждый из этих компонентов мусора должен содержать хотя бы один цикл; в противном случае они были бы собраны, как только их счетчик ссылок (т. е. количество входящих ребер) упал до нуля.

Борьба с неэффективностью обновлений

[ редактировать ]

Увеличение и уменьшение количества ссылок каждый раз, когда ссылка создается или уничтожается, может существенно снизить производительность. Эти операции не только занимают время, но и ухудшают производительность кэша и могут привести к образованию пузырей в конвейере . Даже операции только для чтения, такие как вычисление длины списка, требуют большого количества операций чтения и записи для обновления ссылок с помощью простого подсчета ссылок.

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

Метод подсчета ссылок Дойча-Боброва использует тот факт, что большинство обновлений счетчика ссылок фактически генерируются ссылками, хранящимися в локальных переменных. Она игнорирует эти ссылки, подсчитывая только ссылки в структурах данных, но прежде чем объект с нулевым счетчиком ссылок может быть удален, система должна проверить с помощью сканирования стека и зарегистрировать отсутствие других ссылок на него.

Другой метод, разработанный Генри Бейкером , предполагает отложенное приращение . [4] при котором ссылки, хранящиеся в локальных переменных, не увеличивают соответствующий счетчик ссылок немедленно, а откладывают это до тех пор, пока в этом не возникнет необходимость. Если такая ссылка быстро уничтожается, то обновлять счетчик нет необходимости. Это устраняет большое количество обновлений, связанных с кратковременными ссылками (такими как приведенный выше пример подсчета длины списка). Однако если такая ссылка копируется в структуру данных, тогда в это время должно быть выполнено отложенное приращение. Также очень важно выполнить отложенное приращение до того, как счетчик объекта упадет до нуля, чтобы избежать преждевременного освобождения.

Резкое снижение накладных расходов на обновление счетчиков было получено Леванони и Петранком . [5] [6] Они представляют метод объединения обновлений , который объединяет многие избыточные обновления счетчика ссылок. Рассмотрим указатель, который за заданный интервал выполнения обновляется несколько раз. Сначала он указывает на объект O1, затем к объекту O2и так далее, пока в конце интервала не укажет на какой-нибудь объект On. Алгоритм подсчета ссылок обычно выполняется rc(O1)--, rc(O2)++, rc(O2)--, rc(O3)++, rc(O3)--, ..., rc(On)++. Но большинство этих обновлений избыточны. Чтобы правильно оценить счетчик ссылок в конце интервала, достаточно выполнить rc(O1)-- и rc(On)++. Остальные обновления избыточны.

Леванони и Петранк показали в 2001 году, как использовать такое объединение обновлений в сборщике подсчета ссылок. При использовании объединения обновлений с соответствующей обработкой новых объектов более 99% обновлений счетчиков устраняются для типичных тестов Java.

Интересно, что объединение обновлений также устраняет необходимость использования атомарных операций во время одновременного обновления указателей, что решает проблемы подсчета ссылок в одновременной настройке. Таким образом, объединение обновлений решает третью проблему простого подсчета ссылок (т. е. дорогостоящие накладные расходы при одновременной работе). Леванони и Петранк представили усовершенствованный алгоритм, который может работать одновременно с многопоточными приложениями, использующими только точную синхронизацию. [7]

Блэкберна и МакКинли Метод подсчета скрытых ссылок в 2003 году. [8] сочетает в себе отложенный подсчет ссылок с копирующим питомником, отмечая, что большинство мутаций указателей происходит в молодых объектах. Этот алгоритм достигает производительности, сравнимой с производительностью самых быстрых коллекторов копирования поколений с низким ограниченным временем паузы при подсчете ссылок.

Работа с эталонными циклами

[ редактировать ]

Возможно, самый очевидный способ справиться с эталонными циклами — спроектировать систему так, чтобы избежать их создания. Система может явно запретить эталонные циклы; файловые системы с жесткими ссылками часто делают это. Разумное использование «слабых» (неучтенных) ссылок также может помочь избежать циклов сохранения; например, структура Cocoa рекомендует использовать «сильные» ссылки для отношений «родитель-потомок» и «слабые» ссылки для отношений «потомок-родитель». [9]

Системы также могут быть спроектированы таким образом, чтобы выдерживать или каким-то образом корректировать циклы, которые они создают. Разработчики могут разработать код, который явно «уничтожит» ссылки в структуре данных, когда она больше не нужна, хотя для этого им придется вручную отслеживать время жизни этой структуры данных. Этот метод можно автоматизировать, создав объект-владелец, который выполняет разборку при его уничтожении; например, деструктор объекта Graph может удалить края его GraphNodes, нарушая ссылочные циклы в графе. Циклы можно даже игнорировать в системах с коротким сроком службы и небольшим количеством циклического мусора, особенно если система была разработана с использованием методологии предотвращения циклических структур данных, где это возможно, обычно в ущерб эффективности.

Ученые-компьютерщики также открыли способы автоматического обнаружения и сбора эталонных циклов, не требуя изменений в конструкции структуры данных. Одним из простых решений является периодическое использование отслеживающего сборщика мусора для восстановления циклов; поскольку циклы обычно занимают относительно небольшой объем освобождаемого пространства, сборщик может запускаться гораздо реже, чем обычный сборщик мусора с трассировкой.

Бэкон описывает алгоритм циклического сбора для подсчета ссылок, аналогичный алгоритму отслеживания коллекторов, включая те же теоретические ограничения по времени. Он основан на наблюдении, что цикл может быть изолирован только тогда, когда счетчик ссылок уменьшается до ненулевого значения. Все объекты, на которых это происходит, помещаются в список корней , а затем периодически программа циклически просматривает объекты, доступные из корней. Он знает, что нашел цикл, который можно собрать, когда уменьшение всех счетчиков ссылок в цикле ссылок сводит их все к нулю. [10] Расширенная версия этого алгоритма, разработанная Paz et al. [11] может выполняться одновременно с другими операциями и повышать свою эффективность за счет использования метода объединения обновлений Леванони и Петранка. [5] [6]

Варианты форм

[ редактировать ]

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

Взвешенный подсчет ссылок

[ редактировать ]

При взвешенном подсчете ссылок каждой ссылке присваивается вес , и каждый объект отслеживает не количество ссылающихся на него ссылок, а общий вес ссылающихся на него ссылок. Первоначальная ссылка на вновь созданный объект имеет большой вес, например 2 16 . Всякий раз, когда эта ссылка копируется, половина веса переходит в новую ссылку, а половина веса остается в старой ссылке. Поскольку общий вес не меняется, счетчик ссылок объекта обновлять не нужно.

Уничтожение ссылки уменьшает общий вес на вес этой ссылки. Когда общий вес станет нулевым, все ссылки будут уничтожены. Если предпринимается попытка скопировать ссылку с весом 1, ссылка должна «получить больший вес», прибавляя к общему весу, затем добавляя этот новый вес к ссылке, а затем разделяя его. Альтернативой в этой ситуации является создание объекта косвенной ссылки, первоначальная ссылка на который создается с большим весом, который затем можно разделить.

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

Основная проблема с простым взвешенным подсчетом ссылок заключается в том, что уничтожение ссылки по-прежнему требует доступа к счетчику ссылок, и если будет уничтожено много ссылок, это может вызвать те же самые узкие места, которых мы стремимся избежать. Некоторые модификации взвешенного подсчета ссылок пытаются избежать этого, передавая вес от умирающей ссылки к активной ссылке.

Взвешенный подсчет ссылок был независимо разработан Беваном. [12] и Ватсон и Ватсон [13] в 1987 году.

Косвенный подсчет ссылок

[ редактировать ]

При косвенном подсчете ссылок необходимо отслеживать источник ссылки. Это означает, что на объект сохраняются две ссылки: прямая, которая используется для вызовов; и косвенный, который является частью диффузионного дерева, например, в алгоритме Дейкстры-Шолтена , который позволяет сборщику мусора идентифицировать мертвые объекты. Такой подход предотвращает преждевременное удаление объекта.

Примеры использования

[ редактировать ]

Сбор мусора

[ редактировать ]

В качестве алгоритма сбора подсчет ссылок отслеживает для каждого объекта количество ссылок на него, содержащихся в других объектах. Если счетчик ссылок объекта достигает нуля, объект становится недоступным и может быть уничтожен.

Когда объект уничтожается, счетчики ссылок на любые объекты, на которые ссылается этот объект, также уменьшаются. По этой причине удаление одной ссылки потенциально может привести к освобождению большого количества объектов. Распространенная модификация позволяет сделать подсчет ссылок инкрементным: вместо уничтожения объекта, как только его счетчик ссылок становится равным нулю, он добавляется в список объектов, на которые нет ссылок, и периодически (или по мере необходимости) один или несколько элементов из этого списка удаляются. уничтожен.

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

Подсчет ссылок также используется в файловых системах и распределенных системах, где полная сборка мусора без инкрементальной трассировки занимает слишком много времени из-за размера графа объектов и низкой скорости доступа. [14]

Объектная модель компонента

[ редактировать ]

Microsoft Модель компонентных объектов (COM) и WinRT широко используют подсчет ссылок. Фактически, два из трех методов, которые должны предоставлять все COM-объекты (в интерфейсе IUnknown ), увеличивают или уменьшают счетчик ссылок. Большая часть оболочки Windows и многие приложения Windows (включая MS Internet Explorer , MS Office и бесчисленное количество сторонних продуктов) построены на базе COM, что демонстрирует жизнеспособность подсчета ссылок в крупномасштабных системах. [ нужна ссылка ]

Одной из основных причин подсчета ссылок в COM является обеспечение совместимости между различными языками программирования и системами времени выполнения. Клиенту нужно только знать, как вызывать методы объекта, чтобы управлять жизненным циклом объекта; таким образом, клиент полностью абстрагируется от распределителя памяти, который использует реализация COM-объекта. Типичный пример: программа Visual Basic , использующая COM-объект, не зависит от того, был ли этот объект выделен (и должен быть позже освобожден) распределителем C++ или другим компонентом Visual Basic.

C++ не выполняет подсчет ссылок по умолчанию, следуя своей философии отказа от добавления функций, которые могут повлечь за собой накладные расходы, если пользователь явно не запросил их. Доступ к объектам, которые являются общими, но не принадлежат им, можно получить через ссылку, необработанный указатель или итератор (концептуальное обобщение указателей).

Однако в то же время C++ предоставляет пользователям собственные способы выбора таких функций: C++11 предоставляет интеллектуальные указатели с подсчетом ссылок через std::shared_ptr класс, обеспечивающий автоматическое управление общей памятью динамически выделяемых объектов. Программисты могут использовать это в сочетании со слабыми указателями (через std::weak_ptr), чтобы разорвать циклические зависимости. Срок существования объектов, которые динамически выделяются, но не предназначены для совместного использования, может автоматически управляться с помощью std::unique_ptr.

Кроме того, семантика перемещения C++11 еще больше уменьшает степень необходимости изменения счетчика ссылок за счет удаления глубокой копии, обычно используемой, когда функция возвращает объект, поскольку она позволяет создать простую копию указателя указанного объекта.

Какао (Цель-C)

[ редактировать ]

Платформы Apple Cocoa и Cocoa Touch (и связанные платформы, такие как Core Foundation ) используют ручной подсчет ссылок, во многом подобно COM . Традиционно это выполнялось программистом, вручную отправлявшим retain и release сообщения объектам, но автоматический подсчет ссылок функция компилятора Clang , которая автоматически вставляет эти сообщения по мере необходимости. был добавлен в iOS 5 [15] и Mac OS X 10.7 . [16] В Mac OS X 10.5 в качестве альтернативы подсчету ссылок был представлен сборщик мусора с трассировкой, но он был объявлен устаревшим в OS X 10.8 Objective-C и удален из библиотеки времени выполнения в macOS Sierra . [17] [18] iOS никогда не поддерживала сборщик мусора с трассировкой.

Delphi по большей части не является языком со сборкой мусора, поскольку определяемые пользователем типы по-прежнему необходимо выделять и освобождать вручную; однако он обеспечивает автоматический сбор с использованием подсчета ссылок для нескольких встроенных типов, таких как строки, динамические массивы и интерфейсы, для простоты использования и упрощения общих функций базы данных. Программист должен решить, использовать ли встроенные типы; Программисты Delphi имеют полный доступ к низкоуровневому управлению памятью, как в C/C++. Таким образом, все потенциальные затраты на подсчет ссылок в Delphi при желании можно легко обойти.

Некоторые из причин, по которым подсчет ссылок может быть предпочтительнее других форм сборки мусора в Delphi, включают:

  • Общие преимущества подсчета ссылок, такие как быстрый сбор.
  • Циклы либо не могут возникнуть, либо не встречаются на практике, поскольку ни один из встроенных типов, собирающих мусор, не является рекурсивным. (используя интерфейсы, можно создать такой сценарий, но это не обычное использование)
  • Накладные расходы на размер кода, необходимые для подсчета ссылок, очень малы (на собственном x86 обычно используется одна инструкция LOCK INC, LOCK DEC или LOCK XADD, которая обеспечивает атомарность в любой среде), и для сбора данных не требуется отдельный поток управления, как это было бы понадобится для отслеживания сборщика мусора.
  • Многие экземпляры наиболее часто используемого типа, собираемого мусором, строки, имеют короткое время жизни, поскольку обычно они являются промежуточными значениями при манипулировании строками. Можно было бы оптимизировать использование многих локальных строк, но компилятор в настоящее время этого не делает.
  • Перед изменением строки проверяется счетчик ссылок на строку. Это позволяет изменять строки с числом ссылок 1 напрямую, в то время как строки с большим количеством ссылок копируются перед мутацией. Это позволяет сохранить общее поведение строк Паскаля старого стиля, устраняя при этом затраты на копирование строки при каждом назначении.
  • Поскольку сборка мусора выполняется только для встроенных типов, подсчет ссылок можно эффективно интегрировать в библиотечные процедуры, используемые для управления каждым типом данных, сохраняя при этом накладные расходы, необходимые для обновления счетчика ссылок, на низком уровне. Более того, большая часть библиотеки времени выполнения находится на ассемблере, оптимизированном вручную.
  • Строковый тип можно привести к указателю на char, и таким образом можно выполнять высокопроизводительные операции. Это важно, поскольку и Delphi, и FPC реализуют RTL на языке Pascal. Такие возможности литья есть и в других автоматических типах.

Среда объектно-ориентированного программирования GObject реализует подсчет ссылок на свои базовые типы, включая слабые ссылки . При увеличении и уменьшении ссылок используются атомарные операции для обеспечения безопасности потоков. Значительная часть работы по написанию привязок к GObject из языков высокого уровня заключается в адаптации подсчета ссылок GObject для работы с собственной системой управления памятью языка.

Язык программирования Vala использует подсчет ссылок GObject в качестве основной системы сбора мусора, а также обработку строк с большим количеством копирования. [19]

Perl также использует подсчет ссылок без какой-либо специальной обработки циклических ссылок, хотя (как и в Cocoa и C++ выше) Perl поддерживает слабые ссылки, что позволяет программистам избегать создания цикла.

PHP использует механизм подсчета ссылок для управления внутренними переменными. [20] Начиная с PHP 5.3, он реализует алгоритм из вышеупомянутой статьи Бэкона. PHP позволяет включать и выключать сбор циклов с помощью функций пользовательского уровня. Это также позволяет вручную принудительно запустить механизм продувки.

Python также использует подсчет ссылок и предлагает обнаружение циклов (и может восстанавливать циклы ссылок). [21]

Ржавчина

[ редактировать ]

Как и другие низкоуровневые языки, Rust по умолчанию не обеспечивает подсчет ссылок. Вместо этого любой сконструированный тип будет удален , если он выйдет из области видимости. Когда программисту необходимо определить область действия сконструированного типа, он часто использует время жизни.

Однако язык также предлагает различные альтернативы сложным формам управления памятью. Функциональность подсчета ссылок обеспечивается Rc и Arc типы, которые являются неатомарными и атомарными соответственно.

Например, тип Rc<T> обеспечивает совместное владение значением типа T, выделенный в куче для нескольких ссылок на его данные. [22]

use std::rc::Rc;

struct Cat {
    color: String,
}

fn main() {
    let cat = Cat { color: "black".to_string() };
    let cat = Rc::new(cat);
}

Использование этих конструкций позволяет программистам избежать времени жизни при небольших затратах во время выполнения. Оба счетчика ссылок отслеживают количество владельцев, поскольку они должны автоматически исчезнуть, если владельцев не осталось.

Один примечательный аспект этих типов связан с их использованием в качестве общей ссылки. В Rust общие ссылки не могут изменять хранящиеся в них данные, поэтому Rc часто поставляется в комплекте Cell, и Arc с Mutex, в контекстах, где необходима внутренняя изменчивость.

Изменчивость салона без UnsafeCell также имеет затраты на производительность, поэтому для достижения максимальной производительности некоторые приложения могут потребовать дополнительной сложности. [23]

Squirrel использует подсчет ссылок с обнаружением цикла. Этот крошечный язык относительно неизвестен за пределами индустрии видеоигр; однако это конкретный пример того, как подсчет ссылок может быть практичным и эффективным (особенно в средах реального времени). [ нужна ссылка ]

Swift использует подсчет ссылок для отслеживания и управления памятью экземпляров классов, а также предоставляет weak ключевое слово для создания слабых ссылок. Экземпляры типов значений не используют подсчет ссылок. [24]

Tcl 8 использует подсчет ссылок для управления значениями в памяти ( структуры Tcl Obj ). Поскольку значения Tcl неизменяемы, ссылочные циклы невозможно сформировать, и схема обнаружения циклов не требуется. Операции, которые заменяют значение измененной копией, обычно оптимизируются для изменения оригинала, когда его счетчик ссылок показывает, что он не является общим. Ссылки подсчитываются на уровне структуры данных, поэтому рассмотренных выше проблем с очень частыми обновлениями не возникает.

Xojo также использует подсчет ссылок без какой-либо специальной обработки циклических ссылок, хотя (как и в Cocoa и C++ выше), Xojo поддерживает слабые ссылки, что позволяет программистам избегать создания цикла.

Файловые системы

[ редактировать ]

Многие файловые системы поддерживают счетчик ссылок на любой конкретный блок или файл, например на индексные дескрипторы счетчик ссылок в файловых системах в стиле Unix , которые обычно называются жесткими ссылками . Когда счетчик достигнет нуля, файл можно будет безопасно освободить. Хотя ссылки по-прежнему можно создавать из каталогов , некоторые Unix-системы допускают ссылки только из живых процессов, и могут существовать файлы, существующие вне иерархии файловой системы.

  1. ^ Кевин Дж. Кэссиди (декабрь 1985 г.). Возможность автоматического освобождения памяти с параллельным выполнением программ в среде LISP (PDF) (магистерская диссертация). Военно-морская аспирантура, Монтерей/Калифорния. Здесь: стр.25
  2. ^ Уилсон, Пол Р. (1992). «Методы однопроцессорной сборки мусора» . Материалы международного семинара по управлению памятью . Лондон, Великобритания: Springer-Verlag. стр. 1–42. ISBN  3-540-55940-Х . Раздел 2.1.
  3. ^ Рифат Шахрияр, Стивен М. Блэкберн, Си Ян и Кэтрин С. МакКинли (2013). «Снятие перчаток с помощью Immix подсчета ссылок» (PDF) . 24-я конференция ACM SIGPLAN по системам, языкам и приложениям объектно-ориентированного программирования . OOPSLA 2013. doi : 10.1145/2509136.2509527 . {{cite conference}}: CS1 maint: несколько имен: список авторов ( ссылка )
  4. ^ Генри Бейкер (сентябрь 1994 г.). «Минимизация обновления счетчика ссылок с помощью отложенных и привязанных указателей для функциональных структур данных». Уведомления ACM SIGPLAN . 29 (9): 38–43. CiteSeerX   10.1.1.25.955 . дои : 10.1145/185009.185016 . S2CID   14448488 .
  5. ^ Jump up to: Перейти обратно: а б Йоси Леванони, Эрез Петранк (2001). «Сборщик мусора с подсчетом ссылок на лету для Java» . Материалы 16-й конференции ACM SIGPLAN по объектно-ориентированному программированию, системам, языкам и приложениям . OOPSLA 2001. стр. 367–380. дои : 10.1145/504282.504309 .
  6. ^ Jump up to: Перейти обратно: а б Йоси Леванони, Эрез Петранк (2006). «Сборщик мусора с подсчетом ссылок на лету для Java» . АКМ Транс. Программа. Ланг. Сист . 28 : 31–69. CiteSeerX   10.1.1.15.9106 . дои : 10.1145/1111596.1111597 . S2CID   14777709 .
  7. ^ «Сборщик мусора с подсчетом ссылок на лету для Java» (PDF) . Cs.technion.ac.il . Проверено 24 июня 2017 г.
  8. ^ Стивен Блэкберн; Кэтрин МакКинли (2003). «Скрытый подсчет ссылок: быстрая сборка мусора без долгого ожидания» (PDF) . Материалы 18-й ежегодной конференции ACM SIGPLAN по объектно-ориентированному программированию, системам, языкам и приложениям . OOPSLA 2003. стр. 344–358. дои : 10.1145/949305.949336 . ISBN  1-58113-712-5 .
  9. ^ «Библиотека разработчиков Mac» . Разработчик.apple.com . Проверено 17 декабря 2015 г.
  10. ^ Бэкон, Дэвид Ф.; Раджан, В.Т. (2001). «Сбор параллельных циклов в системах с подсчетом ссылок» (PDF) . ЭКООП 2001 — Объектно-ориентированное программирование . Конспекты лекций по информатике. Том. 2072. стр. 207–235. дои : 10.1007/3-540-45337-7_12 . ISBN  978-3-540-42206-8 . Архивировано из оригинала (PDF) 23 июля 2004 года.
  11. ^ Харель Пас, Дэвид Ф. Бэкон, Эллиот К. Колоднер, Эрез Петранк , В.Т. Раджан (2007). «Эффективный сбор циклов на лету». Транзакции ACM в языках и системах программирования . 29 (4): 20–с. CiteSeerX   10.1.1.10.2777 . дои : 10.1145/1255450.1255453 . S2CID   4550008 . {{cite journal}}: CS1 maint: несколько имен: список авторов ( ссылка )
  12. ^ Беван, Д.И. (1987). «Распределенная сборка мусора с использованием подсчета ссылок». Том II: Параллельные языки на PARLE: Параллельные архитектуры и языки в Европе . Эйндховен, Нидерланды: Springer-Verlag. стр. 176–187. ISBN  0-387-17945-3 .
  13. ^ Уотсон, Пол; Уотсон, Ян (1987). «Эффективная схема сборки мусора для параллельных компьютерных архитектур». Том II: Параллельные языки на PARLE: Параллельные архитектуры и языки в Европе . Эйндховен, Нидерланды: Springer-Verlag. стр. 432–443. ISBN  0-387-17945-3 .
  14. ^ Бруно, Родриго; Феррейра, Паулу (2018). «Исследование алгоритмов сборки мусора для сред больших данных». Обзоры вычислительной техники ACM . 51 : 1–35. дои : 10.1145/3156818 . S2CID   21388487 .
  15. ^ [1] Архивировано 9 июня 2011 г. в Wayback Machine.
  16. ^ «Библиотека разработчиков Mac» . Разработчик.apple.com . Проверено 17 декабря 2015 г.
  17. ^ Сиракузы, Джон (25 июля 2012 г.). «OS X 10.8 Mountain Lion: обзор Ars Technica» . Арс Техника . В разделе «Усовершенствования Objective-C» . Проверено 17 ноября 2016 г. .
  18. ^ «Примечания к выпуску Xcode 8» . Разработчик Apple . 27 октября 2016 г. Архивировано из оригинала 19 марта 2017 г. Проверено 19 марта 2017 г.
  19. ^ «Проекты/Vala/ReferenceHandling — GNOME Wiki!» . ГНОМ. 25 мая 2015 года . Проверено 17 декабря 2015 г.
  20. ^ «PHP: Основы подсчета ссылок — Руководство» . www.php.net . Проверено 1 октября 2020 г.
  21. ^ «1. Расширение Python с помощью C или C++ — документация Python 2.7.11» . Документы.python.org. 5 декабря 2015 года . Проверено 17 декабря 2015 г.
  22. ^ "std::rc — Руст" . doc.rust-lang.org . Проверено 2 ноября 2020 г.
  23. ^ «Ржавая ссылка» . 21 июля 2022. Внутренняя изменчивость. Архивировано из оригинала 24 марта 2024 года . Проверено 22 апреля 2024 г.
  24. ^ «Документация» . docs.swift.org . Проверено 6 декабря 2023 г.
[ редактировать ]
Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: 3c073dbe89f9de93796e0dd652a364fe__1716347820
URL1:https://arc.ask3.ru/arc/aa/3c/fe/3c073dbe89f9de93796e0dd652a364fe.html
Заголовок, (Title) документа по адресу, URL1:
Reference counting - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)