Использование .clear () или разрешение GC позаботиться об этом - PullRequest
2 голосов
/ 09 апреля 2011

В части моего кода создаются два LinkedHashMaps, например:

Map<Byte, Integer> hash1 = new LinkedHashMap<Byte, Integer>();
Map<Byte, Integer> hash2 = new LinkedHashMap<Byte, Integer>();

После этого запускается цикл for для добавления значений в соответствующий HashMap, а затем запускаются HashMapsчерез другой цикл, используемый для создания пакета.Было бы лучше вызвать .clear () после вызова второго цикла или просто позволить сборщику мусора позаботиться об этом?

Ответы [ 2 ]

8 голосов
/ 09 апреля 2011

Если вы не вызовете clear (), GC не позаботится об этом, потому что на хеш-карту будут ссылаться объекты, пока она не выйдет из области видимости.В любом случае, выходя из области видимости, вы можете позволить GC справиться с этим.Вероятно, не будет ощутимой разницы, чтобы сначала очистить его.

1 голос
/ 09 апреля 2011

Вызов clear() на этих картах, вероятно, будет дорогой тратой времени с точки зрения сбора мусора.

Есть три случая для рассмотрения:

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

    Объекты HashMap будут собраны при следующем запуске GC в куче, в которой они содержатся. Вызов clear() не сделает это быстрее и не уменьшит работу, выполняемую GC.

  • Если переменные не собираются выходить из области видимости, но вы не собираетесь повторно использовать HashMaps, то присвоение null им может сделать HashMaps подходящими для GC немного раньше, но JVM может разобраться с этим делом в любом случае. Вызов clear() - пустая трата времени, как указано выше.

  • Если переменные не выходят из области видимости, и вы собираетесь повторно использовать HashMaps, то их очистка может быть правильным решением. Однако реальная цель вызова clear() состоит в том, чтобы избавиться от старых (и предположительно нежелательных) записей карты, которые могут замедлять операции хэш-таблицы, что может привести к неверным результатам.

(Это уточнение комментариев к ответу @ squacknull.)


Чтобы понять, почему вызов clear не помогает ГХ, вам необходимо понять, как работают коллекторы HotSpot. Коллекторы HotSpot «копируют» коллекторы, которые копируют из пространства «из» в пространство «из». Работа выполняется путем рекурсивного отслеживания достижимых объектов в пространстве «из» и копирования их в пространство «в». Затем все оставшиеся объекты проверяются, чтобы увидеть, нужно ли их завершать, а финализуемые объекты рекурсивно отслеживаются и копируются в пространство «в». Наконец, пространство "from" обнуляется, и GC готов. (Это сложнее, если учесть поколения, коллекторов и т. Д., Но не пойдем туда ...)

Если предположить, что HashMap недоступен и не может быть завершен, то ни на одной из фаз маркировки он не найдет ни себя, ни свои внутренние объекты (т. Е. Хэш-массив или цепочки), ни ключи и значения на карте ... при условии, что последнее недоступны другим маршрутом. Таким образом, очистка хеш-массива (что и делает clear()) - это просто очистка элементов объекта, который все равно не будет отслеживаться. Это не влияет на то, что должен делать GC.

...