Như đã chỉ ra, trình biên dịch JIT (just-in-time) có thể tối ưu hóa một vòng lặp trống để loại bỏ các lần lặp không cần thiết. Nhưng bằng cách nào?
Trên thực tế, có hai trình biên dịch JIT: C1 & C2 . Đầu tiên, mã được biên dịch với C1. C1 thu thập các số liệu thống kê và giúp JVM phát hiện ra rằng trong 100% trường hợp, vòng lặp trống của chúng tôi không thay đổi bất cứ điều gì và vô dụng. Trong tình huống này, C2 bước vào sân khấu. Khi mã được gọi rất thường xuyên, nó có thể được tối ưu hóa và biên dịch với C2 bằng cách sử dụng số liệu thống kê được thu thập.
Ví dụ: tôi sẽ kiểm tra đoạn mã tiếp theo (JDK của tôi được đặt thành slowdebug build 9-internal ):
public class Demo {
private static void run() {
for (int i = Integer.MIN_VALUE; i < Integer.MAX_VALUE; i++) {
}
System.out.println("Done!");
}
}
Với các tùy chọn dòng lệnh sau:
-XX:+UnlockDiagnosticVMOptions -XX:CompileCommand=print,*Demo.run
Và có nhiều phiên bản khác nhau của phương pháp chạy của tôi , được biên dịch với C1 và C2 một cách thích hợp. Đối với tôi, biến thể cuối cùng (C2) trông giống như sau:
...
; 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
...
Nó hơi lộn xộn một chút, nhưng nếu bạn nhìn kỹ, bạn có thể nhận thấy rằng không có vòng lặp chạy dài ở đây. Có 3 khối: B1, B2 và B3 và các bước thực hiện có thể là B1 -> B2 -> B3
hoặc B1 -> B3
. Where Freq: 1
- tần suất ước tính chuẩn hóa của một khối thực thi.
javap -v
để xem.