Рассмотрите follwing HashMap.clear()
код:
/**
* Removes all of the mappings from this map.
* The map will be empty after this call returns.
*/
public void clear() {
modCount++;
Entry[] tab = table;
for (int i = 0; i < tab.length; i++)
tab[i] = null;
size = 0;
}
Это кажется, что внутренний массив (table
) из Entry
объекты никогда не shrinked. Так, когда я добавляю 10 000 элементов к карте, и после того вызова map.clear()
, это сохранит 10000, аннулирует в, он - внутренний массив. Так, мой вопрос, как JVM обрабатывает этот массив ничего, и таким образом, HashMap
эффективная память?
Идея в том, что clear()
вызывается только тогда, когда вы хотите повторно использовать HashMap
. Повторное использование объекта должно происходить только по той же причине, по которой он использовался ранее, поэтому есть шанс, что у вас будет примерно одинаковое количество записей. Чтобы избежать бесполезного сжатия и изменения размеров Map
, при вызове clear()
емкость остается неизменной.
Если все, что вы хотите сделать, это выбросить данные в Map
, то вам не нужно (и фактически не следует) вызывать clear()
для нее, а просто очистить все ссылки на саму Map
, в этом случае она будет собрана в мусор.
Вы правы, но, учитывая, что увеличение массива - гораздо более дорогостоящая операция, HashMap вполне может подумать, что «когда пользователь увеличил array, скорее всего, ему снова понадобится массив этого размера позже », и он просто оставит массив вместо того, чтобы уменьшать его и рисковать, что позже придется снова дорого расширить его. Думаю, это эвристика - вы могли бы посоветовать и наоборот.
Еще нужно учитывать, что каждый элемент в table
- это просто ссылка. Установка этих записей в null удалит ссылки из элементов вашей Map
, которые затем будут освобождены для сборки мусора. Таким образом, вы не освобождаете память вообще.
Однако, если вам нужно освободить даже память, используемую самой Map
, то вы должны освободить ее в соответствии с предложением Йоахима Зауэра.
Глядя на исходный код, кажется, что HashMap
никогда не уменьшается. Метод resize
вызывается для удвоения размера, когда это необходимо, но не имеет ничего общего с ArrayList.trimToSize()
.
Если вы используете HashMap
таким образом, что он часто увеличивается и уменьшается, вы можете захотеть просто создать новый HashMap
вместо вызова clear()
.