Давайте посмотрим сегодняjava.utilсумкаWeakHashMapИнструменты.
WeakHashMap определяется следующим образом:
public class WeakHashMap<K,V>
extends AbstractMap<K,V>
implements Map<K,V>
Проще говоря,WeakHashMapДостигнутоMapИнтерфейс, основанный на реализации хеш-таблицы, в этой Карте тип ключаWeakReference. Если соответствующий ключ переработан, объект, на который указывает этот ключ, будет удален из контейнера карты.
WeakHashMap отличается от обычного HashMap.Поведение WeakHashMap в определенной степени основано на поведении сборщика мусора, поэтому некоторый здравый смысл, соответствующий структуре данных Map, будет недействителен на WeakHashMap - возвращаемое значение метода size() станет меньше по мере выполнения программы возвращаемое значение метода isEmpty() изменится с false на true и так далее.
Сильные, мягкие и слабые ссылки
«Ссылка» в Java относится к использованию (указыванию) одного объекта на другой. Типы ключей в WeakHashMap:WeakReference, В Java есть еще два вида ссылок: Strong Reference и Soft Reference.
сильная цитата
Объекты, на которые указывают сильные ссылки, никогда не будут собраны сборщиком мусора.Integer prime = 1;
, первый объект в этом выражении имеет сильную ссылку.
мягкая ссылка
одеялоSoftReferenceОбъект, на который указывает указатель, может быть собран сборщиком мусора, но только если JVM исчерпает память; следующий код может создать мягкую ссылку:
Integer prime = 1;
SoftReference<Integer> soft = new SoftReference<Integer>(prime);
prime = null;
слабая ссылка
Когда на объект ссылается только WeakReference, объект будет собран во время следующего цикла сборки мусора. Мы создаемWeakReference:
Integer prime = 1;
WeakReference<Integer> soft = new WeakReference<Integer>(prime);
prime = null;
Когда присваивается значение null, исходный основной объект будет собран в следующем цикле сборки мусора, потому что на него больше нет сильных ссылок.
Кэширование в памяти с использованием WeakHashMap
Видно, что эта особенность WeakHashMap больше подходит для реализации механизма хранения, аналогичного локальному и in-heap кэшам — инвалидация кэша зависит от поведения сборщика мусора. Предположим сценарий приложения: нам нужно сохранить пакет больших объектов изображения, где значения — это содержимое изображения, а ключ — имя изображения, Здесь нам нужно выбрать подходящий контейнер для сохранения этих объектов .
Использование обычного HashMap не является хорошим выбором, эти большие объекты будут занимать много памяти и не будут восстановлены сборщиком мусора, если только мы не удалим эти элементы до того, как будет отброшен соответствующий ключ. WeakHashMap очень подходит для использования в этом сценарии, следующий код демонстрирует конкретную реализацию:
WeakHashMap<UniqueImageName, BigImage> map = new WeakHashMap<>();
BigImage bigImage = new BigImage("image_id");
UniqueImageName imageName = new UniqueImageName("name_of_big_image"); //强引用
map.put(imageName, bigImage);
assertTrue(map.containsKey(imageName));
imageName = null; //map中的values对象成为弱引用对象
System.gc(); //主动触发一次GC
await().atMost(10, TimeUnit.SECONDS).until(map::isEmpty);
Сначала создайте объект WeakHashMap для хранения экземпляра BigImage. Соответствующим ключом является объект UniqueImageName. При сохранении в WeakHashMap ключ представляет собой слабый ссылочный тип.
Затем мы устанавливаем для imageName значение null, чтобы не было других сильных ссылок на объект bigImage.Согласно правилам WeakHashMap, объект bigImage будет восстановлен в следующем цикле сборки мусора.
пройти черезSystem.gc()
Активно запускайте процесс GC, и тогда вы обнаружите, что WeakHashMap становится пустым.
Суммировать
Эта статья начинается с определения WeakHashMap, а затем представляет три ссылочных типа в Java, чтобы понять принцип работы WeakHashMap, и, наконец, использует пример хранения больших объектов для демонстрации сценария применения WeakHashMap. Код, упомянутый в этой статье, можно найти вGitHub-проектВидеть.