Автоматическое удаление записей в WeakHashMap - PullRequest
0 голосов
/ 19 мая 2018

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

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

Ответы [ 4 ]

0 голосов
/ 19 июня 2018

Ну, сначала мы сузим вопрос.

ВОПРОС: У нас есть WeakHashMap, в котором у нас есть несколько записей.Будут ли эти записи собираться мусором, если записи не используются?

Код ссылки:

WeakHashMap<Object, Object> wkMap = new WeakHashMap<>()
Object obj1 = new Object();
Object obj2 = new Object();

Objcet obj1Meta = new Object();
Objcet obj2Meta = new Object();

wkMap.put(obj1, obj1Meta);
wkMap.put(obj2, obj2Meta);

Прежде всего, речь идет не о том, что используется , а такжеоно имеет какое-либо отношение ко времени: речь идет о том, имеет ли ссылка на карту (wkMap в данном случае) в области действия ;если нет, то вся карта подходит для сборки мусора , это довольно просто.Но если нет, то ...

Нам нужно проверить, являются ли объекты, на которые слабо ссылаются ключи карты, уже мусором или нет.В этом случае obj1 и obj2.

Если эти объекты не были собраны мусором, то их соответствующие записи будут там на карте. Сборщик мусора не собирается утилизировать .Опять просто.

Теперь сложный случай: объекты, на которые слабо ссылаются obj1, obj2, были собраны мусором.Нет необходимости, чтобы их метаданные присутствовали на карте wkMap.В идеале они должны быть собраны мусором, и в конце концов они есть.Но вопрос в том, как ...

Шаг за шагом

  1. Объекты, на которые слабо ссылаются obj1, obj2, становятся пригодными для сбора мусора
  2. сборщик мусора собирает предметы;в этот момент сборщик мусора проверяет наличие слабых ссылок на объект, который он собирает.В нашем случае у нас есть два: ключи двух записей в слабой хэш-карте wkMap.
  3. Если GC обнаружит слабые ссылки на объект, который он собирает, то он проверяет, есть ли к этим ссылкам ReferenceQueueк этому.Если есть, то GC указывает на слабое указание на ReferenceQueue.GC готово.
  4. До сих пор на карте есть записи, которые не подходят для сбора мусора.И он будет там на карте, пока кто-нибудь вручную не установит ключи на null.Подождите, тогда кто это делает?Давайте посмотрим дальше:
  5. Эта ручная очистка выполняется самой WeakHashMap.Давайте проверим код size() внутри WeakHashMap:

    public int size() {
        if (size == 0)
            return 0;
        expungeStaleEntries();
        return size;
    }
    

    Сконцентрируемся на expungeStaleEntries();это тот, который удаляет все записи с карты, которые также присутствуют в ReferenceQueue, и записи становятся пригодными для сбора мусора (единственная очередь ссылок присоединяется ко всем слабым ссылкам, используемым в качестве ключа на карте).).Также проверьте код expungeStaleEntries().

Теперь в двух словах: , если из вашего кода вы вызываете какой-то метод для WeakHashMap, который внутренне вызывает этот метод expungeStaleEntries()только тогда записи получат право на сборку мусора .

Список методов, которые вызывают expungeStaleEntries()

  • size()
  • reSize()
  • isEmpty()
  • putAll()
  • и т. Д.

Надеюсь, это прояснит ситуацию.

0 голосов
/ 19 мая 2018

Будут ли записи этой карты автоматически удаляться по истечении определенного времени?

Зависит от того, когда придет сборщик мусора.Нет гарантии, что он утилизирует «мусор» даже один раз в день.

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

JDK 10 - WeakHashMap

0 голосов
/ 19 мая 2018

В этом коде

 WeakHashMap<Group,String> map = new WeakHashMap<>();

   Group group1 = new Group();
   Group group2 = new Group();

   map.put(group1,"one");
   map.put(group2,"two");

   System.out.println(map);

   group1 = null;

   System.gc();

   System.out.println(map);

В первом операторе print вы увидите, что hashmap имеет два элемента, а во втором операторе print он будет иметь только один элемент.Потому что ссылка на первый элемент теперь нулевая.Так что да, все ключи, чьи ссылки указывают на ноль, будут удалены при следующем запуске GC.

{Group@53e25b76=one, Group@73a8dfcc=two}//First print
{Group@73a8dfcc=two}//Second print
0 голосов
/ 19 мая 2018

Он будет удален при запуске GC, если ваш ключ нигде не указан: ( Ссылка )

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

Время удаления неизвестно:

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

Но будьте осторожны, некоторые объекты, такие как целочисленныемаленькие целые числа, такие как -127-> 127, кешируются JVM, поэтому, если вы используете целочисленный ключ в автозаполнении, он никогда не будет удален с карты.

...