Wie bereits erwähnt, kann der JIT -Compiler (Just-in-Time) eine leere Schleife optimieren, um unnötige Iterationen zu entfernen. Aber wie?
Tatsächlich gibt es zwei JIT-Compiler: C1 und C2 . Zunächst wird der Code mit dem C1 kompiliert. C1 sammelt die Statistiken und hilft der JVM zu erkennen, dass unsere leere Schleife in 100% der Fälle nichts ändert und nutzlos ist. In dieser Situation betritt C2 die Bühne. Wenn der Code sehr oft aufgerufen wird, kann er mithilfe gesammelter Statistiken optimiert und mit dem C2 kompiliert werden.
Als Beispiel werde ich das nächste Code-Snippet testen (mein JDK ist auf slowdebug build 9-internal eingestellt ):
public class Demo {
private static void run() {
for (int i = Integer.MIN_VALUE; i < Integer.MAX_VALUE; i++) {
}
System.out.println("Done!");
}
}
Mit den folgenden Befehlszeilenoptionen:
-XX:+UnlockDiagnosticVMOptions -XX:CompileCommand=print,*Demo.run
Und es gibt verschiedene Versionen meiner Ausführungsmethode , die mit C1 und C2 entsprechend kompiliert wurden. Für mich sieht die letzte Variante (C2) ungefähr so aus:
...
; B1: # B3 B2 <- BLOCK HEAD IS JUNK Freq: 1
0x00000000125461b0: mov dword ptr [rsp+0ffffffffffff7000h], eax
0x00000000125461b7: push rbp
0x00000000125461b8: sub rsp, 40h
0x00000000125461bc: mov ebp, dword ptr [rdx]
0x00000000125461be: mov rcx, rdx
0x00000000125461c1: mov r10, 57fbc220h
0x00000000125461cb: call indirect r10 ; *iload_1
0x00000000125461ce: cmp ebp, 7fffffffh ; 7fffffff => 2147483647
0x00000000125461d4: jnl 125461dbh ; jump if not less
; B2: # B3 <- B1 Freq: 0.999999
0x00000000125461d6: mov ebp, 7fffffffh ; *if_icmpge
; B3: # N44 <- B1 B2 Freq: 1
0x00000000125461db: mov edx, 0ffffff5dh
0x0000000012837d60: nop
0x0000000012837d61: nop
0x0000000012837d62: nop
0x0000000012837d63: call 0ae86fa0h
...
Es ist ein bisschen chaotisch, aber wenn Sie genau hinschauen, werden Sie feststellen, dass es hier keine lange Schleife gibt. Es gibt 3 Blöcke: B1, B2 und B3 und die Ausführungsschritte können B1 -> B2 -> B3
oder sein B1 -> B3
. Wobei Freq: 1
- normalisierte geschätzte Häufigkeit einer Blockausführung.
javap -v
zu sehen.