J'ai juste eu une expérience plutôt désagréable dans notre environnement de production, provoquant OutOfMemoryErrors: heapspace..
J'ai tracé le problème à mon utilisation de l' ArrayList::new
dans une fonction.
Pour vérifier que c'est effectivement pire que la normale création via une déclaration du constructeur (t -> new ArrayList<>()
), j'ai écrit cette petite méthode:
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);
}
}
}
}
L'exécution de la méthode avec l' newMethod=true;
sera la cause de la méthode de l'échec d' OutOfMemoryError
juste après l'indice de frappe 30k. Avec newMethod=false;
le programme ne manque pas, mais garde la pilonnant jusqu'à ce que mort (indice facilement atteint 1,5 million).
Pourquoi est - ArrayList::new
créent un grand nombre Object[]
éléments sur le tas qu'il provoque OutOfMemoryError
si vite?
(En passant, il se produit également lors de la collecte est de type HashSet
.)