Подсчет ссылок - Reference counting

В Информатика, подсчет ссылок это метод программирования для хранения количества Рекомендации, указатели, или же ручки к ресурсу, такому как объект, блок памяти, дисковое пространство и другие.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Леванони и Петранк показали в 2001 году, как использовать такое объединение обновлений в сборщике подсчета ссылок. При использовании объединения обновлений с соответствующей обработкой новых объектов более 99% обновлений счетчика удаляются для типичных тестов Java. Кроме того, необходимость в атомарные операции во время обновления указателя на параллельных процессорах исключено. Наконец, они представили усовершенствованный алгоритм, который может работать одновременно с многопоточными приложениями, используя только точную синхронизацию.[7]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Вывоз мусора

Как алгоритм сбора, подсчет ссылок отслеживает для каждого объекта подсчет количества Рекомендации к нему удерживаются другие объекты. Если счетчик ссылок на объект достигает нуля, объект становится недоступным и может быть уничтожен.

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

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

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

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

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

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

C ++

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

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

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

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

Apple Какао и Какао Touch фреймворки (и связанные фреймворки, такие как Основной фундамент ) использовать ручной подсчет ссылок, как и COM. Традиционно программист вручную отправлял удерживать и релиз сообщения объектам, но Автоматический подсчет ссылок, а Лязг функция компилятора, которая автоматически вставляет эти сообщения по мере необходимости, была добавлена ​​в 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. Delphi в основном не является языком со сборкой мусора, поскольку определяемые пользователем типы по-прежнему должны выделяться и освобождаться вручную. Однако он обеспечивает автоматический сбор для нескольких встроенных типов, таких как строки, динамические массивы и интерфейсы, для простоты использования и упрощения общих функций базы данных. Программист должен решить, использовать ли встроенные типы или нет; Программисты Delphi имеют полный доступ к низкоуровневому управлению памятью, как в C / C ++. Таким образом, при желании можно легко обойти всю потенциальную стоимость подсчета ссылок Delphi.

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

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

GObject

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

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

Perl

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

PHP

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

Python

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

Ржавчина

Rust использует объявленное время жизни в коде для освобождения памяти. Rust имеет Rc и Дуга структура.

Тип Rc обеспечивает совместное владение значением типа Т, размещенный в куче.[22]

использоватьстандартное::rc::Rc;структура Кот{цвет: Нить,}fn главный(){позволятьКот=Кот{цвет: "чернить".нанизывать()};позволятьКот=Rc::новый(Кот);}

Белка

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

Tcl

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

Xojo

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

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

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

Рекомендации

  1. ^ Кевин Дж. Кэссиди (декабрь 1985 г.). Возможность автоматического восстановления памяти с одновременным выполнением программ в среде LISP (PDF) (Дипломная работа). Военно-морская аспирантура, Монтерей / Калифорния. Здесь: стр.25
  2. ^ Уилсон, Пол Р. «Однопроцессорные методы сборки мусора». Материалы международного семинара по управлению памятью. Лондон, Великобритания: Springer-Verlag. С. 1–42. ISBN  3-540-55940-Х. Получено 5 декабря 2009. Раздел 2.1.
  3. ^ Рифат Шахрияр, Стивен М. Блэкберн, Си Ян и Кэтрин С. МакКинли (2013). "Снимая перчатки с помощью подсчета ссылок Immix" (PDF). 24-я конференция ACM SIGPLAN по системам, языкам и приложениям объектно-ориентированного программирования. OOPSLA 2013. Дои:10.1145/2509136.2509527.CS1 maint: несколько имен: список авторов (связь)
  4. ^ Генри Бейкер (Сентябрь 1994 г.). «Минимизация обновления счетчика ссылок с помощью отложенных и привязанных указателей для функциональных структур данных». Уведомления ACM SIGPLAN. 29 (9): 38–43. CiteSeerX  10.1.1.25.955. Дои:10.1145/185009.185016.
  5. ^ а б Йоси Леванони, Эрез Петранк (2001). "Сборщик мусора с подсчетом ссылок на лету для java". Материалы 16-й конференции ACM SIGPLAN по объектно-ориентированному программированию, системам, языкам и приложениям. OOPSLA 2001. С. 367–380. Дои:10.1145/504282.504309.
  6. ^ а б Йоси Леванони, Эрез Петранк (2006). "Сборщик мусора с подсчетом ссылок на лету для java". ACM Trans. Программа. Lang. Syst. 28: 31–69. CiteSeerX  10.1.1.15.9106. Дои:10.1145/1111596.1111597.
  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». Developer.apple.com. Получено 17 декабря 2015.
  10. ^ Бэкон, Дэвид Ф .; Раджан, В. Т. (2001). «Сбор параллельных циклов в системах с подсчетом ссылок» (PDF). ECOOP 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 – es. CiteSeerX  10.1.1.10.2777. Дои:10.1145/1255450.1255453.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 Computing. 51: 1–35. Дои:10.1145/3156818.
  15. ^ [1] В архиве 9 июня 2011 г. Wayback Machine
  16. ^ «Библиотека разработчика Mac». Developer.apple.com. Получено 17 декабря 2015.
  17. ^ Сиракуза, Джон (25 июля 2012 г.). «OS X 10.8 Mountain Lion: обзор Ars Technica». 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». Docs.python.org. 5 декабря 2015 г.. Получено 17 декабря 2015.
  22. ^ "std :: rc - Rust". doc.rust-lang.org. Получено 2 ноября 2020.

внешняя ссылка