Hello, -XX:TieredStopAtLevel=1 flag is often used in some applications (e.g. Spring Boot based) to reduce start-up time.
With this flag I've spotted huge performance degradation of Array::newInstance comparing to plain constructor call. I've used this benchmark @State(Scope.Thread) @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) public class ArrayInstantiationBenchmark { @Param({"10", "100", "1000"}) private int length; @Benchmark public Object newInstance() { return Array.newInstance(Object.class, length); } @Benchmark public Object constructor() { return new Object[length]; } } On C2 (JDK 11) both methods perform the same: Benchmark (length) Mode Cnt Score Error Units ArrayInstantiationBenchmark.constructor 10 avgt 50 11,557 ± 0,316 ns/op ArrayInstantiationBenchmark.constructor 100 avgt 50 86,944 ± 4,945 ns/op ArrayInstantiationBenchmark.constructor 1000 avgt 50 520,722 ± 28,068 ns/op ArrayInstantiationBenchmark.newInstance 10 avgt 50 11,899 ± 0,569 ns/op ArrayInstantiationBenchmark.newInstance 100 avgt 50 86,805 ± 5,103 ns/op ArrayInstantiationBenchmark.newInstance 1000 avgt 50 488,647 ± 20,829 ns/op On C1 however there's a huge difference (approximately 8 times!) for length = 10: Benchmark (length) Mode Cnt Score Error Units ArrayInstantiationBenchmark.constructor 10 avgt 50 11,183 ± 0,168 ns/op ArrayInstantiationBenchmark.constructor 100 avgt 50 92,215 ± 4,425 ns/op ArrayInstantiationBenchmark.constructor 1000 avgt 50 838,303 ± 33,161 ns/op ArrayInstantiationBenchmark.newInstance 10 avgt 50 86,696 ± 1,297 ns/op ArrayInstantiationBenchmark.newInstance 100 avgt 50 106,751 ± 2,796 ns/op ArrayInstantiationBenchmark.newInstance 1000 avgt 50 840,582 ± 24,745 ns/op Pay attention that performance for length = {100, 1000} is almost the same. I suppose it's a bug somewhere on VM because both methods just allocate memory and do zeroing elimination and subsequently there shouldn't be such a huge difference between them. Sergey Tsypanov