WeakHashMap в Java

Java задняя часть JVM API

Давайте посмотрим сегодня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-проектВидеть.

использованная литература

  1. Weak references - how useful are they?
  2. Guide to WeakHashMap in Java