Рубрики
Без рубрики

Слабые ссылки в Java

Узнайте о слабых ссылках в Java и их распространенных сценариях использования.

Автор оригинала: baeldung.

1. Обзор

В этой статье мы рассмотрим концепцию слабой ссылки – на языке Java.

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

2. Слабые ссылки

Объект со слабой ссылкой очищается сборщиком мусора, когда он слабо доступен.

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

Во-первых, сборщик мусора очищает слабую ссылку, поэтому референт больше недоступен. Затем ссылка помещается в очередь ссылок (если таковая существует), откуда мы можем ее получить.

В то же время, ранее слабо достижимые объекты будут доработаны.

2.1. Слабые и мягкие ссылки

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

Поскольку мягкая ссылка действует как кэш, она может оставаться доступной, даже если сам референт недоступен. На самом деле, мягкая ссылка имеет право на сбор, если и только если:

  • Референт не является строго достижимым
  • Доступ к мягкой ссылке в последнее время отсутствует

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

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

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

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

Для получения дополнительной информации ознакомьтесь с нашим руководством по WeakHashMap .

Еще одна область, в которой они могут быть использованы, – это проблема пропущенного прослушивателя .

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

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

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

4. Работа Со Слабыми Ссылками

Слабые ссылки представлены классом java.lang.ref.WeakReference . Мы можем инициализировать его, передав ссылку в качестве параметра. При необходимости мы можем предоставить java.lang.ref.ReferenceQueue :

Object referent = new Object();
ReferenceQueue referenceQueue = new ReferenceQueue<>();

WeakReference weakReference1 = new WeakReference<>(referent);
WeakReference weakReference2 = new WeakReference<>(referent, referenceQueue);

Референт ссылки может быть извлечен методом get и удален вручную с помощью метода clear :

Object referent2 = weakReference1.get();
weakReference1.clear();

Схема безопасной работы с такого рода ссылками такая же, как и с мягкими ссылками:

Object referent3 = weakReference2.get();
if (referent3 != null) {
    // GC hasn't removed the instance yet
} else {
    // GC has cleared the instance
}

5. Заключение

В этом кратком руководстве мы рассмотрели низкоуровневую концепцию слабой ссылки в Java и сосредоточились на наиболее распространенных сценариях их использования.