Ответ
Вызов list.clear() для ArrayList<Integer> с 1 млн элементов не освобождает память, занятую внутренним массивом, но позволяет GC собрать сами объекты Integer.
Детализация:
-
Память внутреннего массива (
elementData)- Метод
clear()устанавливаетsize = 0и обнуляет (null) ссылки в массиве, но не уменьшает его емкость (capacity). - Массив из 1 млн ссылок (~4 байта каждая при
-XX:+UseCompressedOops) продолжает занимать ~4 МБ.
- Метод
-
Память объектов
Integer- После
clear()ссылки на 1 млн объектовIntegerтеряются. - Если других ссылок на эти объекты нет, они становятся кандидатами на сборку мусора (GC).
- Память под сами объекты (примерно 16 байт на объект) будет освобождена во время следующей сборки мусора.
- После
Пример и управление памятью:
import java.util.ArrayList;
public class MemoryDemo {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
// Заполняем 1 млн элементов
for (int i = 0; i < 1_000_000; i++) {
list.add(i); // Автоупаковка int -> Integer
}
System.out.println("Size after fill: " + list.size());
// 1. clear() освобождает только ссылки
list.clear();
System.out.println("Size after clear: " + list.size());
// Внутренний массив все еще имеет capacity на 1 млн элементов (~4 МБ).
// 2. Чтобы уменьшить внутренний массив, нужно:
list.trimToSize(); // Теперь capacity = size = 0
// ИЛИ
list = new ArrayList<>(); // Старый ArrayList будет собран GC
}
}
Итог: Сразу после clear() остается ~4 МБ под внутренний массив ссылок. Память объектов Integer (~16 МБ) освободится после работы GC.