Освобождает ли вызов метода clear() у ArrayList память, занимаемую элементами?

«Освобождает ли вызов метода clear() у ArrayList память, занимаемую элементами?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Да, но с важным уточнением.

Метод ArrayList.clear() выполняет две операции:

  1. Освобождает ссылки на все элементы, хранящиеся в списке. Это позволяет сборщику мусора (Garbage Collector) удалить сами объекты-элементы, если на них больше нет других ссылок.
  2. Обнуляет счетчик размера (size = 0).

Однако, внутренний массив (Object[] elementData), в котором хранятся ссылки на элементы, остается прежнего размера. Его емкость (capacity) не уменьшается. Это сделано для производительности: если в очищенный список снова начнут добавлять элементы, не потребуется немедленное дорогостоящее перевыделение памяти и копирование массива.

Как действительно уменьшить потребление памяти? После clear() можно вызвать метод trimToSize(). Он создает новый внутренний массив минимально необходимого размера (по умолчанию 0, а при следующем добавлении - 10), копируя в него старые данные (которых нет), тем самым освобождая память от большого пустого массива.

Пример:

ArrayList<String> list = new ArrayList<>(1000); // capacity = 1000
list.add("A");
list.add("B");
System.out.println(list.size()); // 2

list.clear(); // Элементы "A" и "B" могут быть собраны GC.
               // Но массив elementData.length все еще равен 1000.
System.out.println(list.size()); // 0

list.trimToSize(); // Теперь elementData.length станет 0 (или DEFAULT_CAPACITY=10)
                   // Старый массив на 1000 ячеек будет удален GC.

Вывод: clear() освобождает память от элементов, но не от избыточной емкости внутреннего массива. Для полного освобождения используйте trimToSize().