Эффективна ли память Java HashMap.clear () и remove ()? - PullRequest
39 голосов
/ 11 мая 2010

Рассмотрим следующий код 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 объектов никогда не уменьшается.Поэтому, когда я добавляю 10000 элементов на карту и после этого вызова map.clear(), она сохраняет 10000 нулей во внутреннем массиве.Итак, мой вопрос: как JVM обрабатывает этот массив ничего, и, следовательно, HashMap эффективна ли память?

Ответы [ 4 ]

61 голосов
/ 11 мая 2010

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

Если все, что вы хотите сделать, это отбросить данные в Map, то вам не нужно (и фактически не следует) вызывать clear() для него, а просто очистить все ссылки на сам Map в в каком случае это будет мусор в конечном итоге.

10 голосов
/ 11 мая 2010

Глядя на исходный код , он выглядит так, как будто HashMap никогда не сжимается. Метод resize вызывается для удвоения размера всякий раз, когда это необходимо, но не имеет ничего общего ArrayList.trimToSize().

Если вы используете HashMap таким образом, чтобы он часто увеличивался и уменьшался, вы можете просто создать новый HashMap вместо вызова clear().

4 голосов
/ 11 мая 2010

Еще одна вещь, которую следует учитывать, - это то, что каждый элемент в table является просто ссылкой. Установка этих записей в нуль удалит ссылки из элементов в вашем Map, которые затем будут свободны для сборки мусора. Так что вы совсем не освобождаете память.

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

4 голосов
/ 11 мая 2010

Вы правы, но, учитывая, что увеличение массива является гораздо более дорогой операцией, для HashMap вполне разумно думать, что «как только пользователь увеличит массив, скорее всего, ему понадобится массив такого размера позже» и просто оставьте массив вместо того, чтобы уменьшать его и рисковать, чтобы потом его дорого расширять. Я полагаю, это эвристика - вы могли бы защищать и наоборот.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...