¿Horrible rendimiento y gran espacio de almacenamiento dinámico de referencia de constructor Java 8?
Acabo de tener una experiencia bastante desagradable en nuestro entorno de producción, causandoOutOfMemoryErrors: heapspace..
Rastreé el problema con mi uso deArrayList::new
en una función
Para verificar que esto realmente está funcionando peor que la creación normal a través de un constructor declarado (t -> new ArrayList<>()
), Escribí el siguiente método pequeño:
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);
}
}
}
}
Ejecutando el método connewMethod=true;
hará que el método falle conOutOfMemoryError
justo después de que el índice llegue a 30k. ConnewMethod=false;
el programa no falla, pero sigue golpeando hasta que se mata (el índice alcanza fácilmente 1.5 millones).
Por queArrayList::new
crear tantosObject[]
elementos en el montón que causaOutOfMemoryError
¿tan rapido?
(Por cierto, también ocurre cuando el tipo de colección esHashSet
.)