У меня был довольно неприятный опыт в нашей производственной среде, вызвав OutOfMemoryErrors: heapspace..
Я проследил проблему до использования ArrayList::new
в функции.
Чтобы убедиться, что это действительно хуже, чем нормальное создание через объявленный конструктор (t -> new ArrayList<>()
), я написал следующий небольшой метод:
public class TestMain {
public static void main(String[] args) {
boolean newMethod = false;
Map<Integer,List<Integer>> map = new HashMap<>();
int index = 0;
while(true){
if (newMethod) {
map.computeIfAbsent(index, ArrayList::new).add(index);
} else {
map.computeIfAbsent(index, i->new ArrayList<>()).add(index);
}
if (index++ % 100 == 0) {
System.out.println("Reached index "+index);
}
}
}
}
Запуск метода с помощью newMethod=true;
приведет к тому, что метод завершится с ошибкой OutOfMemoryError
сразу после обращения индекса 30k. С newMethod=false;
программа не терпит неудачу, но продолжает ударяться до тех пор, пока не будет убита (индекс легко достигнет 1,5 миллионов).
Почему ArrayList::new
создает так много элементов Object[]
в куче, что вызывает OutOfMemoryError
так быстро?
(Кстати, это также происходит, когда тип коллекции HashSet
.)