Triển khai trình biên dịch đúng lúc ART

Thời gian chạy Android (ART) bao gồm trình biên dịch đúng lúc (JIT) với cấu hình mã giúp liên tục cải thiện hiệu suất của các ứng dụng Android khi chúng chạy. Trình biên dịch JIT bổ sung cho trình biên dịch trước thời hạn (AOT) hiện tại của ART và cải thiện hiệu suất thời gian chạy, tiết kiệm dung lượng lưu trữ cũng như tăng tốc độ cập nhật ứng dụng và hệ thống. Nó cũng cải thiện trình biên dịch AOT bằng cách tránh làm chậm hệ thống trong quá trình cập nhật ứng dụng tự động hoặc biên dịch lại ứng dụng trong quá trình cập nhật qua mạng (OTA).

Mặc dù JIT và AOT sử dụng cùng một trình biên dịch với bộ tối ưu hóa tương tự nhưng mã được tạo có thể không giống nhau. JIT sử dụng thông tin loại thời gian chạy, có thể thực hiện nội tuyến tốt hơn và có thể biên dịch thay thế ngăn xếp (OSR), tất cả đều tạo ra mã hơi khác nhau.

Kiến trúc JIT

Kiến trúc JIT
Hình 1. Kiến trúc JIT.

biên soạn JIT

Biên dịch JIT bao gồm các hoạt động sau:

Comp hướng dẫn hồ sơ
Hình 2. Biên dịch theo hướng dẫn hồ sơ.
  1. Người dùng chạy ứng dụng, sau đó kích hoạt ART để tải tệp .dex .
    • Nếu tệp .oat (nhị phân AOT cho tệp .dex ) có sẵn, ART sẽ sử dụng trực tiếp tệp đó. Mặc dù các tệp .oat được tạo thường xuyên nhưng chúng không phải lúc nào cũng chứa mã được biên dịch (nhị phân AOT).
    • Nếu tệp .oat không chứa mã được biên dịch, ART sẽ chạy qua JIT và trình thông dịch để thực thi tệp .dex .
  2. JIT được bật cho bất kỳ ứng dụng nào không được biên dịch theo bộ lọc biên dịch speed (có nội dung "biên dịch nhiều nhất có thể từ ứng dụng").
  3. Dữ liệu hồ sơ JIT được chuyển vào một tệp trong thư mục hệ thống mà chỉ ứng dụng mới có thể truy cập.
  4. Trình nền biên dịch AOT ( dex2oat ) phân tích tệp đó để điều khiển quá trình biên dịch của nó.

    Trình nền JIT
    Hình 3. Các hoạt động của daemon JIT.

Dịch vụ Google Play là một ví dụ được sử dụng bởi các ứng dụng khác hoạt động tương tự như thư viện dùng chung.

Quy trình làm việc JIT

Kiến trúc JIT
Hình 4. Luồng dữ liệu JIT.
  • Thông tin hồ sơ được lưu trữ trong bộ đệm mã và chịu sự thu thập rác dưới áp lực bộ nhớ.
    • Không có gì đảm bảo ảnh chụp nhanh được chụp khi ứng dụng ở chế độ nền sẽ chứa dữ liệu hoàn chỉnh (tức là mọi thứ đã được JITed).
    • Không có nỗ lực nào để đảm bảo mọi thứ đều được ghi lại (vì điều này có thể ảnh hưởng đến hiệu suất thời gian chạy).
  • Các phương thức có thể ở ba trạng thái khác nhau:
    • thông dịch (mã dex)
    • JIT biên soạn
    • AOT biên soạn
    Nếu tồn tại cả mã JIT và AOT (ví dụ: do không tối ưu hóa nhiều lần), mã JITed sẽ được ưu tiên.
  • Yêu cầu bộ nhớ để chạy JIT mà không ảnh hưởng đến hiệu suất của ứng dụng trên nền trước tùy thuộc vào ứng dụng được đề cập. Các ứng dụng lớn yêu cầu nhiều bộ nhớ hơn các ứng dụng nhỏ. Nhìn chung, các ứng dụng lớn có dung lượng ổn định khoảng 4 MB.

Bật ghi nhật ký JIT

Để bật tính năng ghi nhật ký JIT, hãy chạy các lệnh sau:

adb root
adb shell stop
adb shell setprop dalvik.vm.extra-opts -verbose:jit
adb shell start

Tắt JIT

Để tắt JIT, hãy chạy các lệnh sau:

adb root
adb shell stop
adb shell setprop dalvik.vm.usejit false
adb shell start

Buộc biên soạn

Để buộc biên dịch, hãy chạy như sau:

adb shell cmd package compile

Các trường hợp sử dụng phổ biến để buộc biên dịch một gói cụ thể:

  • Dựa trên hồ sơ:
    adb shell cmd package compile -m speed-profile -f my-package
    
  • Đầy đủ:
    adb shell cmd package compile -m speed -f my-package
    

Các trường hợp sử dụng phổ biến để buộc biên dịch tất cả các gói:

  • Dựa trên hồ sơ:
    adb shell cmd package compile -m speed-profile -f -a
    
  • Đầy đủ:
    adb shell cmd package compile -m speed -f -a
    

Xóa dữ liệu hồ sơ

Để xóa dữ liệu hồ sơ và xóa mã đã biên dịch, hãy chạy như sau:

  • Đối với một gói:
    adb shell cmd package compile --reset my-package
    
  • Đối với tất cả các gói:
    adb shell cmd package compile --reset -a