I just had a rather unpleasant experience in our production environment, causing OutOfMemoryErrors: heapspace..
I traced the issue to my use of ArrayList::new
in a function.
To verify that this is actually performing worse than normal creation via a declared constructor (t -> new ArrayList<>()
), I wrote the following small method:
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);
}
}
}
}
Running the method with newMethod=true;
will cause the method to fail with OutOfMemoryError
just after index hits 30k. With newMethod=false;
the program does not fail, but keeps pounding away until killed (index easily reaches 1.5 milion).
Why does ArrayList::new
create so many Object[]
elements on the heap that it causes OutOfMemoryError
so fast?
(By the way - it also happens when the collection type is HashSet
.)