Найти тему

WeakReference — котики, которых можно потерять

Оглавление

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

Т.е. WeakReference позволяет нам удерживать объекты в памяти, но при этом не мешает сборщику мусора удалять их, если на объекты больше нет сильных ссылок (стандартный тип ссылки: например, val cat = Cat()).

Как происходит решение об удалении WeakReference:

Когда мы создаём WeakReference, внутри него используются слабые (weak) ссылки. Эти ссылки не учитываются при подсчёте "живых" ссылок на объект, поэтому объект может быть удалён, если на него больше нет сильных ссылок.

Немного подробней про удаление:

  1. Когда системе не хватает памяти, сборщик мусора начинает свою работу. Он ищет объекты, на которые нет сильных ссылок (обычные) и которые могут быть удалены без вреда для корректной работы приложения.
  2. Когда сборщик мусора определяет, что объект, на который ссылается WeakReference, доступен только через слабые ссылки, он удаляет объект из памяти. После этого попытка доступа к объекту через WeakReference вернет null.
  3. Сначала удаляются объекты, на которые ссылаются WeakReference, а затем — объекты, на которые ссылаются SoftReference. Сборщик мусора рассматривает WeakReference как кандидатов для удаления при каждом своём запуске, в то время как SoftReference предоставляют большую гибкость, позволяя объектам оставаться в памяти до тех пор, пока не начнётся нехватка памяти.

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

Пример:

Возьмём метод, который загружает какое-то изображение и отображает его в ImageView:

val imageViewRef = WeakReference(imageView): создание слабой ссылки (WeakReference) на объект ImageView. Это делается для предотвращения утечки памяти. Слабая ссылка позволит сборщику мусора удалить объект ImageView, если на него больше нет сильных ссылок, даже если операция загрузки изображения ещё не завершена. Полезно при уничтожении активити.

Когда использовать WeakReference?

  1. Кэширование: WeakReference часто используется в кэшировании данных, когда мы хотим хранить объекты до тех пор, пока на них есть спрос, но не хотим мешать системе удалять их, если они перестают быть нужными.
  2. Подписчики и обозреватели: в паттерне Observer, где объекты должны быть отслеживаемыми, но не должны удерживаться в памяти, когда на них нет активных обозревателей.
  3. Кэширование изображений в приложениях: когда изображение больше не отображается на экране, оно может быть удалено из памяти.
  4. Временное хранение объектов, таких как обработчики задач или коллбэки, которые не должны блокировать сборку мусора этих объектов, если они больше не нужны. Про коллбэки может быть не совсем понятно. Пример:
-2

Плюсы WeakReference:

  • Полезен в сценариях, где нужно хранить объекты, но не удерживать их в памяти, если на них нет активных ссылок.
  • Предотвращение утечек памяти: использование WeakReference помогает избегать утечек памяти.

Минусы WeakReference:

  • Дополнительная сложность: использование WeakReference требует более внимательного управления ссылками, что может сделать код сложнее для понимания. Впрочем, так можно сказать о многих вещах, поэтому не особо и минус.
  • Нет гарантии, что объект будет доступен при обращении к нему через WeakReference, поскольку он может быть собран мусором в любой момент.
-3

Дубль статей в телеграмме — https://t.me/android_junior

Мои заметки в телеграмме — https://t.me/android_junior_notes

P.S. сделано с помощью https://docs.oracle.com/en/java/javase/20/docs/api/java.base/java/lang/ref/WeakReference.html, ChatGPT и Midjourney