Карта clear vs null

У меня есть карта, которую я использую для хранения динамических данных, которые отбрасываются, как только они создаются (т.е. используются, они быстро потребляются). Он реагирует на взаимодействие пользователя в том смысле, что когда пользователь нажимает кнопку, карта заполняется, а затем данные используются для выполнения некоторой работы, а затем карта больше не нужна.

Итак, мой вопрос - лучший подход к опорожнению карты? должен ли я устанавливать его значение null каждый раз или я должен называть clear()? Я знаю, что ясно, что оно линейно во времени. Но я не знаю, как сравнить эту стоимость с тем, чтобы каждый раз создавать карту. Размер карты не является постоянным, считается, что он может работать от n до 3n элементов между творениями.

Ответ 1

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

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

Ответ 2

Ну, это зависит от того, сколько памяти вы можете бросить на него. Если у вас много, то это не имеет значения. Однако установка самой карты в значение null означает, что вы освободили сборщик мусора - если только карта имеет ссылки на экземпляры внутри нее, сборщик мусора может собирать не только карту, но и любые экземпляры внутри нее. Clear очищает карту, но она должна перебирать все на карте, чтобы установить каждую ссылку на нуль, и это происходит во время вашего времени выполнения, которое вы можете контролировать - сборщик мусора, по существу, должен делать эту работу в любом случае, поэтому пусть это делает его вещь. Просто отметьте, что установка его в значение null не позволяет его повторно использовать. Типичным примером повторного использования переменной карты может быть:

Map<String, String> whatever = new HashMap<String, String();
// .. do something with map
whatever = new HashMap<String, String>();

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

Ответ 3

Я чувствую, что обнуление существующей карты дешевле, чем clear(). Поскольку создание объектов очень дешево в современных JVM.

Ответ 4

Короткий ответ: используйте Collection.clear(), если это слишком сложно, чтобы сохранить collection arround.

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

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

Ответ 5

Если вы всегда держите карту, она будет предложена для старого поколения. Если у каждого пользователя есть одна соответствующая карта, количество карт в старом поколении пропорционально количеству пользователей. Это может привести к полному GC более часто, когда число пользователей увеличивается.

Ответ 6

Вы можете использовать оба с одинаковыми результатами.

В одном из предыдущих ответов отмечается, что clear, как ожидается, займет постоянное время в реализации зрелой карты. Не проверяя исходный код типа HashMap, TreeMap, ConcurrentHashMap, я ожидал бы, что их метод clear займет постоянное время, плюс amortized расходы на сбор мусора.

Другой плакат отмечает, что общая карта не может быть нулевой. Ну, это возможно, если вы этого захотите, но вы делаете это с помощью объекта proxy, который инкапсулирует правильную карту и завершает ее нуль при необходимости, Конечно, вам нужно будет реализовать класс прокси-карты самостоятельно.

Map<Foo, Bar> myMap = new ProxyMap<Foo, Bar>();
    // Internally, the above object holds a reference to a proper map,
    // for example, a hash map. Furthermore, this delegates all calls
    // to the underlying map. A true proxy.
myMap.clear();
    // The clear method simply reinitializes the underlying map.

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

Существует еще одна причина для clear вместо обнуления, даже если карта не используется совместно. Ваша карта может быть создана внешним клиентом, например factory, поэтому, если вы очистите свою карту, отключив ее, вы можете coupling самостоятельно использовать factory без необходимости. Почему объект, который очищает карту, должен знать, что вы создаете свои карты с помощью Guava Maps.newHashMap(), когда Бог знает, какие параметры? Даже если это не является реалистичной проблемой в вашем проекте, оно по-прежнему окупается, чтобы привести себя в соответствие со зрелыми практиками.

По вышеуказанным причинам и при прочих равных условиях я проголосую за clear.

НТН.