Ну, сначала мы сузим вопрос.
ВОПРОС: У нас есть 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
.В идеале они должны быть собраны мусором, и в конце концов они есть.Но вопрос в том, как ...
Шаг за шагом
- Объекты, на которые слабо ссылаются
obj1
, obj2
, становятся пригодными для сбора мусора - сборщик мусора собирает предметы;в этот момент сборщик мусора проверяет наличие слабых ссылок на объект, который он собирает.В нашем случае у нас есть два: ключи двух записей в слабой хэш-карте
wkMap
. - Если GC обнаружит слабые ссылки на объект, который он собирает, то он проверяет, есть ли к этим ссылкам
ReferenceQueue
к этому.Если есть, то GC указывает на слабое указание на ReferenceQueue
.GC готово. - До сих пор на карте есть записи, которые не подходят для сбора мусора.И он будет там на карте, пока кто-нибудь вручную не установит ключи на
null
.Подождите, тогда кто это делает?Давайте посмотрим дальше: Эта ручная очистка выполняется самой WeakHashMap
.Давайте проверим код size()
внутри WeakHashMap
:
public int size() {
if (size == 0)
return 0;
expungeStaleEntries();
return size;
}
Сконцентрируемся на expungeStaleEntries()
;это тот, который удаляет все записи с карты, которые также присутствуют в ReferenceQueue
, и записи становятся пригодными для сбора мусора (единственная очередь ссылок присоединяется ко всем слабым ссылкам, используемым в качестве ключа на карте).).Также проверьте код expungeStaleEntries()
.
Теперь в двух словах: , если из вашего кода вы вызываете какой-то метод для WeakHashMap
, который внутренне вызывает этот метод expungeStaleEntries()
только тогда записи получат право на сборку мусора .
Список методов, которые вызывают expungeStaleEntries()
size()
reSize()
isEmpty()
putAll()
- и т. Д.
Надеюсь, это прояснит ситуацию.