Hohe Leistung und großer Heap-Speicherbedarf der Java 8-Konstruktorreferenz?
Ich hatte gerade eine ziemlich unangenehme Erfahrung in unserer Produktionsumgebung und verursachteOutOfMemoryErrors: heapspace..
Ich habe das Problem auf die Verwendung von @ zurückgeführArrayList::new
in einer Funktion.
Um zu überprüfen, ob dies über einen deklarierten Konstruktor tatsächlich eine schlechtere Leistung als die normale Erstellung erbringt t -> new ArrayList<>()
) Schrieb ich die folgende kleine Methode:
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);
}
}
}
}
Methode mit @ ausführnewMethod=true;
führt dazu, dass die Methode mit @ fehlschläOutOfMemoryError
kurz nachdem der Index 30k erreicht hat. MitnewMethod=false;
das Programm schlägt nicht fehl, sondern schlägt weiter zu, bis es getötet wird (Index erreicht leicht 1,5 Millionen).
Warum tutArrayList::new
so viele erstellenObject[]
Elemente auf dem Haufen, den es verursachtOutOfMemoryError
so schnell
(Übrigens - es kommt auch vor, wenn der Auflistungstyp @ isHashSet
.)