Java List.clear() vs. List = null
Я запускаю свое приложение под профилировщиком, и использование памяти намного выше, чем я ожидаю, когда объекты все еще существуют, когда они больше не нужны. Большинство из них находятся в списках, в которых объект списка вышел из контекста.
Доходит ли сборщик мусора дольше, чтобы высвободить объекты, которые находятся в списке, даже если сам список больше не ссылается? Если да, освободят ли они раньше, если я вызову clear() в списке до того, как он выйдет из контекста?
thanks - dave
Ответы
Ответ 1
Что касается механики сбора мусора, вы спрашиваете, имеют ли корни GC какие-либо приоритеты над всеми другими, транзитивно достижимыми объектами, которые обнаруживаются как недостижимые. Учитывая то, как работают алгоритмы маркерной развертки, нет никакой разницы между этими двумя. Все такие объекты мусора будут отмечены в одном и том же проходе, и внутренняя доступность объекта из недосягаемого объекта не влияет на это.
Поиск множества недостижимых объектов, которые еще не были восстановлены, не является чем-то необычным, и на самом деле это оправдывает общую производительность приложений: только при сбое памяти будет выполняться GC. Если вас беспокоит размер вашей кучи, просто уменьшите максимальный размер кучи. Это приведет к более частому сбору мусора.
Ответ 2
Если мы возьмем ArrayList
в качестве примера, метод clear()
сделает следующее:
public void clear() {
modCount++;
// Let gc do its work
for (int i = 0; i < size; i++)
elementData[i] = null;
size = 0;
}
В принципе, если элементы списка не упоминаются нигде в коде, вам действительно не нужно (или, по крайней мере, ничего не набирать), чтобы вызвать clear()
. Вам также не нужно назначать null
для Списка, потому что это будет сбор мусора, как только он выпадет из области видимости.
Ответ 3
Да. clear
удалит ссылки на объекты в списке, по крайней мере, реализация списка ArrayList
сделает это. Однако, если весь ваш объект List
все равно выходит из области видимости, вы ничего не получаете.
Ответ 4
Я знаю, что получил ваш ответ, но хотел уточнить... если ваш старый ген имеет размер 1 ГБ, но вы только храните в нем 1 МБ, тогда нет никакой необходимости в том, чтобы GC работал. На самом деле вы не хотите, чтобы он запускал в это время, потому что если бы это было тогда, у вас были бы события stop-the-world, вызванные алгоритмом развертки меток (по метке и повторной настройке) отметьте фазы).
GC срабатывает только при наличии давления на память.