Triển khai trình biên dịch đúng thời điểm ART

Android Runtime (ART) bao gồm một trình biên dịch vừa kịp thời (JIT) với tính năng phân tích 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ạy. Trình biên dịch JIT bổ sung cho trình biên dịch trước thời gian (AOT) hiện tại của ART, đồng thời cải thiện hiệu suất thời gian chạy, tiết kiệm dung lượng lưu trữ và tăng tốc độ cập nhật ứng dụng và hệ thống. Công cụ này 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 không dây (OTA).

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

Cấu trúc JIT

Cấu trúc JIT
Hình 1. Cấu trúc JIT.

Biên dịch JIT

Quá trình biên dịch JIT bao gồm các hoạt động sau:

Thành phần kết hợp theo hướng dẫn của hồ sơ
Hình 2. Biên dịch theo hướng dẫn của hồ sơ.
  1. Người dùng chạy ứng dụng, sau đó ứng dụng sẽ kích hoạt ART để tải tệp .dex.
    • Nếu có tệp .oat (tệp nhị phân AOT cho tệp .dex), 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 không phải lúc nào các tệp này cũng chứa mã đã biên dịch (tệp 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 mọi ứng dụng không được biên dịch theo bộ lọc biên dịch speed ("biên dịch nhiều nhất có thể từ ứng dụng").
  3. Dữ liệu hồ sơ JIT được kết xuất 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 cú pháp tệp đó để thúc đẩy quá trình biên dịch.

    Trình nền JIT
    Hình 3. Hoạt động của trình nền JIT.

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

Quy trình làm việc JIT

Cấu trúc JIT
Hình 4. Luồng dữ liệu JIT.
  • Thông tin phân tích tài nguyên được lưu trữ trong bộ nhớ đệm mã và phải được thu gom rác khi có áp lực bộ nhớ.
    • Không có gì đảm bảo rằng ảnh chụp nhanh được chụp khi ứng dụng đang chạy ở chế độ nền sẽ chứa dữ liệu đầy đủ (tức là mọi thứ đã được JIT).
    • 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).
  • Phương thức có thể ở 3 trạng thái:
    • được diễn giải (mã dex)
    • Biên dịch JIT
    • Biên dịch AOT
    Nếu cả mã JIT và mã AOT đều tồn tại (ví dụ: do việc huỷ tối ưu hoá lặp lại), thì bạn nên sử dụng mã JIT.
  • Yêu cầu về 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 phụ thuộc vào ứng dụng có liên quan. Ứng dụng lớn cần nhiều bộ nhớ hơn ứng dụng nhỏ. Nhìn chung, các ứng dụng lớn sẽ ổn định ở mức khoảng 4 MB.

Bật tính năng 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 dịch

Để buộc biên dịch, hãy chạy lệ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ả 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
    

Xoá dữ liệu hồ sơ

Trên Android 13 trở xuống

Để xoá dữ liệu hồ sơ cục bộ và xoá mã đã biên dịch, hãy chạy mã sau:

adb shell pm compile --reset 

Trên Android 14 trở lên

Cách chỉ xoá dữ liệu hồ sơ cục bộ:

adb shell pm art clear-app-profiles 

Lưu ý: Không giống như lệnh dành cho Android 13 trở xuống, lệnh này không xoá dữ liệu hồ sơ bên ngoài (".dm") được cài đặt cùng với ứng dụng.

Để xoá dữ liệu hồ sơ cục bộ và xoá mã đã biên dịch được tạo từ dữ liệu hồ sơ cục bộ (tức là để đặt lại về trạng thái cài đặt), hãy chạy các lệnh sau:

adb shell pm compile --reset 

Lưu ý: Lệnh này không xoá mã được biên dịch được tạo từ dữ liệu hồ sơ bên ngoài (".dm") được cài đặt cùng với ứng dụng.

Để xoá tất cả mã đã biên dịch, hãy chạy lệnh sau:

adb shell cmd package compile -m verify -f 

Lưu ý: Lệnh này giữ lại dữ liệu hồ sơ cục bộ.