Слабая ссылка

Материал из Википедии — свободной энциклопедии
Перейти к: навигация, поиск

В программировании слабая ссылка (англ. weak reference) — специфический вид ссылок на динамически создаваемые объекты в системах со сборкой мусора. Отличается от обычных ссылок тем, что не учитывается сборщиком мусора при выявлении объектов, подлежащих удалению. Ссылки, не являющиеся слабыми, также иногда именуют «сильными».

Содержание понятия[править | править вики-текст]

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

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

Чтобы избежать подобных проблем, язык или среда программирования могут поддерживать так называемые слабые ссылки. Такие ссылки используются так же, как и обычные, но не влияют на сборку мусора, поскольку не учитываются механизмом подсчёта ссылок, и объект, на который существуют такие ссылки, может быть удалён, если только на него не существует обычных ссылок (которые в этом контексте могут именоваться «сильными ссылками»).

Реализация и использование[править | править вики-текст]

В распространённых сейчас языках программирования со сборкой мусора — Java и C#, — слабые ссылки поддерживаются на уровне системных библиотек. В Java для этого служат классы java.lang.ref.WeakReference и java.lang.ref.SoftReference, в C# — класс System.WeakReference. Используются они принципиально одинаково: когда требуется сохранить слабую ссылку, создаётся объект-реферер (экземпляр класса WeakReference), которому передаётся сильная ссылка. Переданная сильная ссылка тут же освобождается, и в реферере хранится ссылка, существование которой не может помешать сборщику мусора удалить соответствующий объект. Когда требуется воспользоваться слабой ссылкой, у реферера вызывается метод get() (в C# — свойство Target), который возвращает сильную ссылку на объект, если он ещё существует, или null, если объект уже удалён сборщиком мусора. Поскольку get возвращает именно сильную ссылку, во время её использования объект удалён не будет, но после того, как использование этой ссылки прекратилось, он снова становится доступным для сборки мусора. Таким образом, при каждом использовании слабой ссылки программа должна обязательно проверить её на равенство NULL.

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

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

Чтобы слабые ссылки на уже не существующие объекты не засоряли память, системные библиотеки предоставляют механизмы для учёта таких ссылок. Вариантом такого механизма являются очереди ссылок — специальные объекты, которые передаются рефереру при создании. Когда сборщик мусора уничтожает объект, на который ссылается слабая ссылка, он помещает в ранее переданную очередь ссылок ссылку на соответствующий реферер. Таким образом, программе доступен список рефереров, содержащих «мёртвые» ссылки, и она может выполнить их удаление в любой подходящий момент.

Ссылки[править | править вики-текст]