Android Runtime (ART) là môi trường thực thi ứng dụng Android, được giới thiệu trong Android 5.0 Lollipop để thay thế Dalvik. Cải tiến chính là biên dịch AOT mã byte DEX thành mã máy gốc trực tiếp trong quá trình cài đặt ứng dụng, loại bỏ vấn đề lâu năm về làm nóng trình biên dịch JIT. Theo Google, 2024, ART cung cấp mức tăng hiệu suất lên đến 20–30% so với Dalvik trong khi vẫn duy trì khả năng tương thích ngược hoàn toàn với định dạng DEX.
Những điểm chính
Android Runtime (ART) là môi trường thực thi ứng dụng biên dịch mã byte DEX thành mã máy gốc trước khi thực thi. Không giống như Dalvik sử dụng biên dịch Just-In-Time trong thời gian chạy, ART thực hiện biên dịch Ahead-Of-Time (AOT) trong quá trình cài đặt APK. Sự thay đổi kiến trúc cơ bản này dẫn đến tăng tốc đáng kể cho các ứng dụng và giảm mức tiêu thụ điện năng.
ART lần đầu tiên xuất hiện như một tùy chọn thử nghiệm trong Android 4.4 KitKat. Các nhà phát triển có thể bật nó trong cài đặt nhà phát triển và kiểm tra ứng dụng của họ. Trong Android 5.0 Lollipop, ART trở thành môi trường thực thi mặc định và Dalvik đã bị loại bỏ hoàn toàn khỏi nền tảng. Vào thời điểm Android 7.0 Nougat được phát hành, ART đã có chế độ biên dịch kết hợp.
Quyết định thay thế Dalvik bằng ART không phải là bất ngờ. Công việc trên môi trường mới bắt đầu vào năm 2012 khi Google nhận ra những hạn chế của cách tiếp cận JIT. Các mục tiêu chính: tăng tốc khởi động ứng dụng, giảm tải CPU và giảm mức tiêu thụ điện năng. Sự phát triển được dẫn dắt bởi Android Runtime Group, trước đây đã làm việc về tối ưu hóa Dalvik.
ART sử dụng cùng kiến trúc dựa trên thanh ghi như Dalvik, nhưng với trình biên dịch được thiết kế lại hoàn toàn. Thay vì trình thông dịch và trình biên dịch JIT, ART bao gồm trình biên dịch AOT dex2oat, chuyển đổi các tệp DEX thành tệp nhị phân ELF trong quá trình cài đặt. Kết quả là các ứng dụng trên ART khởi động với hiệu suất gốc ngay lập tức, không cần giai đoạn làm nóng.
ART vẫn giữ các nguyên tắc chính của Dalvik: cô lập ứng dụng thông qua các tiến trình riêng biệt, kiến trúc dựa trên thanh ghi và hỗ trợ định dạng DEX. Tuy nhiên, quá trình triển khai nội bộ đã được viết lại hoàn toàn. Thay vì trình thông dịch Dalvik, ART bao gồm ba chế độ thực thi: trình thông dịch, trình biên dịch JIT và trình biên dịch AOT dex2oat. Việc lựa chọn chế độ phụ thuộc vào giai đoạn vòng đời của ứng dụng.
Thành phần chính của ART là dex2oat (dalvik executable to optimized android translator). Tiện ích này chạy trong quá trình cài đặt ứng dụng (từ Android 7.0 — cũng chạy trong quá trình tối ưu hóa nền). dex2oat đọc các tệp DEX từ APK, tối ưu hóa mã byte và tạo tệp OAT — một tệp nhị phân ELF với mã gốc. Các tệp OAT được lưu trữ trong thư mục /data/dalvik-cache/.
# Kiểm tra tệp OAT trên thiết bị
adb shell ls -la /data/dalvik-cache/arm64/
# Biên dịch lại bắt buộc ứng dụng
adb shell cmd package compile -m speed com.example.app
Hệ thống ART bao gồm nhiều mô-đun kết nối với nhau. Trình biên dịch dex2oat chịu trách nhiệm tạo mã gốc. Bộ thu gom rác (GC) quản lý việc giải phóng bộ nhớ. Trình thông dịch thực thi mã ít được gọi mà không cần biên dịch. Trình hồ sơ theo dõi các phương thức nóng để biên dịch kết hợp. Mỗi mô-đun có thể hoạt động độc lập, làm cho ART linh hoạt và có thể mở rộng.
Bắt đầu từ Android 7.0 Nougat, ART sử dụng cách tiếp cận kết hợp để biên dịch, kết hợp ưu điểm của JIT và AOT. Trong quá trình cài đặt ứng dụng, ART không còn thực hiện biên dịch AOT đầy đủ nữa — thay vào đó, ứng dụng chạy ở chế độ thông dịch với biên dịch JIT các phương thức nóng. Điều này giảm thời gian cài đặt và dung lượng lưu trữ.
Một trình hồ sơ nền hoạt động song song. Nó thu thập thống kê thực thi: phương thức nào được gọi thường xuyên nhất, nhánh mã nào được thực thi, lớp nào được tải. Sau khi tích lũy đủ dữ liệu (thường sau 2–3 lần khởi động ứng dụng), ART chạy dex2oat trong nền và chỉ biên dịch các phương thức nóng đã hồ sơ thành mã gốc.
ART hỗ trợ một số chế độ biên dịch, được quản lý thông qua system_server. Chế độ “speed” biên dịch tất cả các phương thức bằng AOT (hiệu suất tối đa, cài đặt chậm). Chế độ “speed-profile” chỉ biên dịch các phương thức nóng đã hồ sơ (cân bằng giữa tốc độ và kích thước). Chế độ “verify” chỉ xác minh mã byte mà không biên dịch (dung lượng tối thiểu, thông dịch). Theo mặc định, speed-profile được sử dụng — tối ưu cho hầu hết các ứng dụng.
| Chế độ | Biên dịch | Thời gian cài đặt | Hiệu suất |
|---|---|---|---|
| speed | AOT đầy đủ | Chậm | Tối đa |
| speed-profile | AOT hồ sơ | Nhanh | Cao |
| verify | Không biên dịch | Tức thì | Thông dịch |
| space | AOT tối thiểu | Trung bình | Trung bình |
Trình hồ sơ thu thập dữ liệu thực thi vào các tệp .prof đặc biệt. Mỗi ứng dụng lưu trữ hồ sơ của nó trong /data/misc/profiles/. Khi đạt ngưỡng (thường là 1000 mẫu), trình hồ sơ khởi chạy dex2oat để biên dịch các phương thức nóng đã xác định. Các hồ sơ được giữ lại giữa các bản cập nhật ứng dụng, giúp tăng tốc tối ưu hóa lại sau các bản cập nhật OTA của hệ thống.
Dọn rác trong ART được cải thiện đáng kể so với Dalvik. Thay vì Concurrent Mark and Sweep (CMS) đơn luồng, ART sử dụng bộ thu gom thế hệ với một số tối ưu hóa: bộ thu gom di chuyển (nén đống), không gian đối tượng lớn (lưu trữ riêng cho các đối tượng lớn) và nén đồng thời (nén song song).
Thời gian tạm dừng GC điển hình trong ART là 2–3 ms so với 5–10 ms trong Dalvik. Điều này trở nên khả thi nhờ một số cơ chế. Thứ nhất, ART sử dụng read-barrier thay vì stop-the-world cho các giai đoạn đồng thời. Thứ hai, bộ thu gom thế hệ chỉ xử lý thế hệ trẻ của các đối tượng trong hầu hết các chu kỳ mà không chạm đến toàn bộ đống. Thứ ba, không gian đối tượng lớn (LOS) được phân bổ riêng và không tham gia vào các chu kỳ GC thông thường.
// Bật nhật ký GC để gỡ lỗi
System.logV("ART", "GC trigger: allocation failed");
// Gọi GC bắt buộc (không khuyến nghị trong sản xuất)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Debug.getRuntimeIStats();
}
Mặc dù GC đã được cải thiện, rò rỉ bộ nhớ vẫn là một vấn đề quan trọng. Một nguyên nhân cụ thể của ART là tải các thư viện gốc qua JNI mà không giải phóng đúng cách. Nếu mã gốc cấp phát bộ nhớ qua malloc nhưng không gọi free, ART không thể giải phóng bộ nhớ này — nó nằm ngoài đống được quản lý. Công cụ AddressSanitizer trong Android NDK giúp xác định các rò rỉ như vậy.
ART và Dalvik là hai triển khai khác nhau cơ bản của cùng một nhiệm vụ: thực thi các ứng dụng Android. Sự khác biệt ảnh hưởng đến tất cả các cấp: từ biên dịch đến quản lý bộ nhớ. Dưới đây là so sánh các thông số hiệu suất và khả năng tương thích chính.
Ưu điểm chính của ART là loại bỏ quá trình làm nóng JIT. Trên Dalvik, ứng dụng có thể bị chậm trong 3–10 giây đầu trong khi JIT biên dịch các phương thức nóng. Trên ART, tất cả các phương thức đã được biên dịch thành mã gốc (hoặc sẽ được biên dịch trong nền). Điều này đặc biệt đáng chú ý trong các trò chơi và ứng dụng có giao diện nặng: sự khác biệt về fps có thể đạt 15–20% nghiêng về ART.
| Thông số | Dalvik | ART |
|---|---|---|
| Biên dịch | JIT (trong thời gian chạy) | AOT + hybrid (khi cài đặt) |
| Thời gian khởi động | 3–10 giây (làm nóng) | Tức thì |
| Kích thước APK | ~6–7 MB (DEX) | +20% (OAT) |
| Tạm dừng GC | 5–10 ms | 2–3 ms |
| Tiêu thụ điện | Cao hơn (JIT làm nóng CPU) | Thấp hơn (mã gốc) |
Tất cả các ứng dụng được viết cho Dalvik đều chạy trên ART mà không cần thay đổi. Google đảm bảo khả năng tương thích ngược đầy đủ ở cấp mã byte DEX. Ngoại lệ là mã sử dụng API nội bộ cụ thể của Dalvik thông qua phản chiếu: các thành viên của lớp dalvik.system.DexFile được đánh dấu @hide trong Android SDK. Mã như vậy cần được cập nhật để sử dụng API công khai.
ART trở thành môi trường thực thi Android đầu tiên hỗ trợ các tính năng Java 8 gốc. Bắt đầu từ Android 7.0, ART bao gồm desugaring — quá trình chuyển đổi cấu trúc Java 8 (lambda, tham chiếu phương thức, Stream API) thành mã Java 7 tương đương. Điều này cho phép sử dụng cú pháp hiện đại mà không mất khả năng tương thích với các thiết bị cũ.
Desugaring được thực hiện bởi trình biên dịch D8 và hoạt động như sau. Mã nguồn có lambda được chuyển đổi thành một phương thức tổng hợp trong cùng một lớp và lambda được thay thế bằng một lời gọi invoke-custom. Thời gian chạy của ART bao gồm hỗ trợ cho lệnh invoke-custom, được thêm vào dành riêng cho Java 8. Trên các thiết bị chạy Android 6.0 trở xuống, lambda được desugar thành các lớp ẩn danh.
// Lambda Java 8 — desugaring trong ART
button.setOnClickListener(v -> handleClick(v));
// Sau khi desugaring (tương đương Java 7)
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handleClick(v);
}
});
Không phải tất cả các tính năng Java 8 đều được desugaring hỗ trợ. API java.time (ngày và giờ) chỉ khả dụng thông qua desugar_jdk_libs — một thư viện bổ sung được thêm vào build.gradle. Stream API cũng yêu cầu desugar_jdk_libs. java.util.function và Optional hoạt động mà không cần các phụ thuộc bổ sung. Hỗ trợ đầy đủ Java 8 có sẵn trên các thiết bị chạy Android 8.0 trở lên mà không cần desugaring.
Mặc dù ART tương thích ngược, một số thực hành tối ưu hóa cải thiện hiệu suất cụ thể trên môi trường này. Khuyến nghị chính là giảm thiểu phản chiếu. ART biên dịch các phương thức hiện rõ tại thời điểm biên dịch thành các lời gọi mã máy trực tiếp. Phản chiếu buộc ART tạo các stubs bổ sung, làm chậm quá trình thực thi 10–15%.
Bắt đầu từ Android 9.0, ART đã giới thiệu hỗ trợ cho App Startup Optimization. Nhà phát triển có thể đánh dấu các lớp khởi tạo trong tệp kê khai thông qua <initialization> và ART sẽ tải trước chúng khi khởi động ứng dụng. Điều này giảm thời gian khởi động từ 5–15% cho các ứng dụng có nhiều plugin hoặc thư viện.
<!-- App Startup Optimization trong AndroidManifest.xml -->
<application>
<profileable
android:shell="true"
android:enable="true" />
</application>
Để đo hiệu suất trên ART, hãy sử dụng systrace và perfetto. Systrace hiển thị thời gian biên dịch dex2oat, tần suất GC và tốc độ kết xuất khung hình. Perfetto cung cấp thông tin chi tiết hơn: phân phối luồng, thời gian chuyển đổi JNI, tải thư viện gốc. Khởi chạy: adb shell perfetto -o /data/misc/perfetto-traces/trace.perfetto -t 10s sched freq idle am wm.
Câu hỏi thường gặp
ART (Android Runtime) là môi trường thực thi ứng dụng Android biên dịch mã ứng dụng thành mã máy trong quá trình cài đặt. Điều này tăng tốc khởi động và vận hành ứng dụng so với môi trường Dalvik cũ.
ART biên dịch mã trước (AOT) trong quá trình cài đặt ứng dụng, trong khi Dalvik biên dịch nó từng phần trong thời gian chạy (JIT). Do đó, trên ART, các ứng dụng khởi động nhanh hơn và tiêu thụ ít điện năng hơn.
Chạy adb shell getprop và tìm thuộc tính persist.sys.dalvik.vm.lib.2. Giá trị “libart.so” có nghĩa là ART, “libdvm.so” có nghĩa là Dalvik. Tất cả các thiết bị chạy Android 5.0+ đều sử dụng ART làm môi trường thực thi.
Tối thiểu. Bản thân ứng dụng vẫn ở định dạng APK với các tệp DEX. ART tạo một tệp OAT bổ sung trong /data/dalvik-cache/, chiếm nhiều hơn 10–20% dung lượng so với DEX gốc, nhưng dung lượng lưu trữ này không được tính vào kích thước APK.
Có, ART hỗ trợ hầu hết các tính năng Java 8 thông qua cơ chế desugaring. Lambda, tham chiếu phương thức và giao diện chức năng hoạt động trên tất cả các thiết bị chạy Android 5.0+. Stream API và java.time yêu cầu thư viện desugar_jdk_libs.
Tổng kết
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm