Использование WeakReference в Java и Android для эффективности
Пройдите тест, узнайте какой профессии подходите
Быстрый ответ
WeakReference
в Java и Android отлично подходят для оптимизации использования памяти: они позволяют сборщику мусора удалять объекты, на которые отсутствуют сильные ссылки. В мире Android, с его ограниченной памятью, использование таких ссылок чрезвычайно актуально, поскольку они позволяют "подставить под удар" объекты перед всемогущим сборщиком мусора.
MyObject obj = new MyObject(); // Создаём объект
WeakReference<MyObject> weakRef = new WeakReference<>(obj); // Оборачиваем его в WeakReference
obj = null; // Удаляем сильную связь. Теперь есть только слабая ссылка
// Проверяем, выжил ли объект или его "съел" сборщик мусора
MyObject retrievedObj = weakRef.get();
if (retrievedObj != null) {
// Объект всё ещё жив 🥳🎉
} else {
// Спасибо "трудящемуся" сборщику мусора 😢
}
Ключевые моменты:
new WeakReference<>(obj)
: Вы создали слабую ссылку.weakRef.get()
: Вы проверяете, уцелела ли ваша "жертва".
Использование слабых ссылок для кеширования
Кеширование с использованием слабых ссылок позволяет изящно контролировать жизненный цикл кешированных объектов: они не будут занимать память дольше необходимого, и при нехватке ресурсов без раздумий подвергнутся очистке. Они словно герои утилизации памяти, готовые на тотальное самопожертвование.
WeakHashMap<MyKey, Bitmap> imageCache = new WeakHashMap<>();
// ...
// Кладём битмап в кэш, желая, чтобы он оставался там как можно дольше
imageCache.put(myKey, myBitmap);
WeakHashMap
автоматически удаляет записи с устаревшими ключами, исключая их из общего цикла работы.
Наблюдение с помощью слабых ссылок
Слабые ссылки в наблюдательных паттернах помогают избегать необоснованного удержания объектов, которые больше не выполняют свои функции. Они словно последний эхо, дрожащий в тишине — если не поддерживать его, он исчезает.
WeakReference<MyListener> weakListenerRef = new WeakReference<>(myListener);
myObservables.addListener(weakListenerRef);
Слушатели будут собраны сборщиком мусора, как только прекратится их активное использование в коде, что позволит сохранить память и освободить их от рассылки извещений.
Применение слабых ссылок в Android View
В Android WeakReference
можно использовать для временного хранения ссылок на объекты View, предотвращая замедление сбора мусора при уничтожении Activity.
WeakReference<View> weakViewRef = new WeakReference<>(myView);
// ...
View view = weakViewRef.get();
if(view != null) {
// Выводим тост с приветствием
}else{
// Вью уж больше нет, одна пустота.
}
Визуализация
Представьте память вашего приложения как вечеринку, где гости в руках держат маленькие флажки (WeakReference
🚩). Сборщик мусора (🚪👤) регулярно проверяет, готовы ли уйти те гости, которые не заняты активным общением (т.е. на которых нет сильных ссылок).
Гости: [👩💼🚩, 👨🔧🚩, 👨🎨, 👩🚀🚩, 👨🚒]
Если гость оказался одинок и у него только флажок...
Действия сборщика: 👩💼🚩➡️🚪👤 (Гость с флажком покидает вечеринку)
Вечеринка после вмешательства сборщика мусора:
Остались: [👨🔧, 👨🎨, 👩🚀🚩, 👨🚒]
Подводные камни
Как и с гостями, которые планируют уйти в своё удовольствие, внезапная "чистка" может вызвать сумятицу. Работа GC носит непредсказуемый характер, и это подогревает впечатление случайности исчезновения слабых ссылок. При работе с WeakReference
всегда стоит быть готовым к неожиданностям.
Сохраните другие типы ссылок
Java предлагает специализированные типы ссылок: SoftReference
и PhantomReference
.
SoftReference
– это своего рода резервное хранилище для объектов, в которое сборщик мусора заглядывает в последнюю очередь.PhantomReference
используется для организации очистки после сбора мусора, что можно сравнить с уборкой после вечеринки.
Полезные материалы
- WeakReference (Java Platform SE 8) — официальная документация Java SE 8 по
WeakReference
. - WeakReference – Android Developers — руководство Android-разработчиков по
WeakReference
. - Предотвращение утечек памяти в Android — Подробная статья о способах учесть утечки памяти с помощью
WeakReference
при разработке на Android. - "Различия между Soft и Weak Reference в Java" — Обсуждение на Stack Overflow, где детально объясняется когда применять
WeakReference
в Java. - Понимание ссылок в Java от IBM Developer — Публикация IBM Developer с подробным описанием типов ссылок в Java, в которой также говорится о
WeakReference
.