Android Runtime (ART) — สภาพแวดล้อมรันไทม์ของแอปพลิเคชัน Android ที่ถูกนำมาใช้ใน Android 5.0 Lollipop เพื่อแทนที่ Dalvik นวัตกรรมหลักคือการคอมไพล์ AOT ล่วงหน้าของ DEX byte-code เป็นโค้ดเครื่องเนทีฟโดยตรงเมื่อติดตั้งแอปพลิเคชัน ซึ่งช่วยขจัดปัญหาการอุ่นเครื่อง JIT คอมไพเลอร์ที่ยาวนานหลายปี ตามข้อมูลของ Google, 2024 ART ช่วยเพิ่มประสิทธิภาพได้ถึง 20–30% เมื่อเทียบกับ Dalvik พร้อมรักษาความเข้ากันได้ย้อนหลังอย่างสมบูรณ์กับรูปแบบ DEX
ประเด็นสำคัญ
Android Runtime (ART) — สภาพแวดล้อมรันไทม์ของแอปพลิเคชันที่คอมไพล์ DEX byte-code เป็นโค้ดเครื่องเนทีฟก่อนถึงเวลารัน แตกต่างจาก Dalvik ที่ใช้การคอมไพล์แบบ Just-In-Time ระหว่างการทำงาน ART ดำเนินการคอมไพล์แบบ Ahead-Of-Time (AOT) เมื่อติดตั้ง APK การเปลี่ยนแปลงสถาปัตยกรรมพื้นฐานนี้ทำให้แอปพลิเคชันเร็วขึ้นอย่างมีนัยสำคัญและลดการใช้พลังงาน
ART ปรากฏครั้งแรกในฐานะ ตัวเลือกทดลอง ใน Android 4.4 KitKat นักพัฒนาสามารถเปิดใช้งานได้ในการตั้งค่าสำหรับนักพัฒนาและทดสอบแอปพลิเคชันของตน ใน Android 5.0 Lollipop ART กลายเป็นสภาพแวดล้อมรันไทม์เริ่มต้น และ Dalvik ถูกลบออกจากแพลตฟอร์มอย่างสมบูรณ์ เมื่อถึงเวลาที่ Android 7.0 Nougat ออกมา ART ได้รับโหมดการคอมไพล์แบบไฮบริด
การตัดสินใจแทนที่ Dalvik ด้วย ART ไม่ได้เกิดขึ้นอย่างกะทันหัน การทำงานกับสภาพแวดล้อมใหม่เริ่มขึ้นในปี 2012 เมื่อ Google ตระหนักถึงข้อจำกัดของแนวทาง JIT เป้าหมายหลัก: เร่งการเริ่มต้นแอปพลิเคชัน ลดภาระของ CPU และลดการใช้พลังงาน การพัฒนานำโดยทีม Android Runtime Group ซึ่งก่อนหน้านี้ทำงานเกี่ยวกับการเพิ่มประสิทธิภาพของ Dalvik
ART ใช้ สถาปัตยกรรมแบบรีจิสเตอร์ เดียวกันกับ Dalvik แต่มีคอมไพเลอร์ที่ออกแบบใหม่ทั้งหมด แทนที่จะใช้อินเทอร์พรีเตอร์และ JIT คอมไพเลอร์ ART มี AOT คอมไพเลอร์ dex2oat ซึ่งแปลงไฟล์ DEX เป็นไบนารี ELF เมื่อติดตั้ง ผลลัพธ์คือแอปพลิเคชันบน ART เริ่มต้นด้วยประสิทธิภาพเนทีฟทันที โดยไม่มีช่วงอุ่นเครื่อง
ART ยังคงหลักการสำคัญของ Dalvik ไว้: การแยกแอปพลิเคชันผ่านโพรเซสแยกกัน สถาปัตยกรรมแบบรีจิสเตอร์ และการรองรับรูปแบบ DEX อย่างไรก็ตาม การนำไปใช้ภายในถูกเขียนขึ้นใหม่ทั้งหมด แทนที่อินเทอร์พรีเตอร์ของ Dalvik ART ประกอบด้วยสามโหมดการทำงาน: อินเทอร์พรีเตอร์ JIT คอมไพเลอร์ และ AOT คอมไพเลอร์ dex2oat การเลือกโหมดขึ้นอยู่กับระยะของวงจรชีวิตของแอปพลิเคชัน
ส่วนประกอบหลักของ ART คือ dex2oat (dalvik executable to optimized android translator) ยูทิลิตี้นี้จะทำงานเมื่อติดตั้งแอปพลิเคชัน (ตั้งแต่ Android 7.0 เป็นต้นไป — ยังทำงานเมื่อปรับแต่งในพื้นหลังด้วย) dex2oat อ่านไฟล์ DEX จาก APK เพิ่มประสิทธิภาพ byte-code และสร้าง ไฟล์ OAT — ไบนารี ELF พร้อมโค้ดเนทีฟ ไฟล์ OAT ถูกเก็บไว้ในไดเรกทอรี /data/dalvik-cache/
# การตรวจสอบไฟล์ OAT บนอุปกรณ์
adb shell ls -la /data/dalvik-cache/arm64/
# การบังคับคอมไพล์แอปพลิเคชันใหม่
adb shell cmd package compile -m speed com.example.app
ระบบ ART ประกอบด้วยโมดูลที่เชื่อมต่อกันหลายส่วน คอมไพเลอร์ dex2oat ทำหน้าที่สร้างโค้ดเนทีฟ ตัวเก็บขยะ (GC) จัดการการคืนหน่วยความจำ อินเทอร์พรีเตอร์ทำงานโค้ดที่เรียกใช้นานๆ ครั้งโดยไม่ต้องคอมไพล์ โปรไฟเลอร์ติดตาม hot-methods สำหรับการคอมไพล์แบบไฮบริด แต่ละโมดูลสามารถทำงานแยกกันได้ ทำให้ ART มีความยืดหยุ่นและปรับขนาดได้
ตั้งแต่ Android 7.0 Nougat ART ใช้ แนวทางแบบไฮบริด ในการคอมไพล์ ซึ่งรวมข้อดีของ JIT และ AOT เข้าด้วยกัน เมื่อติดตั้งแอปพลิเคชัน ART จะไม่ดำเนินการคอมไพล์ AOT ทั้งหมดอีกต่อไป — แต่แอปพลิเคชันจะเริ่มทำงานในโหมดแปลความหมายพร้อมการคอมไพล์ JIT สำหรับ hot-methods ซึ่งช่วยลดเวลาในการติดตั้งและพื้นที่จัดเก็บ
ในขณะเดียวกัน โปรไฟเลอร์พื้นหลัง (background profiler) จะทำงาน มันรวบรวมสถิติการทำงาน: เมธอดใดถูกเรียกใช้บ่อยที่สุด โค้ดสาขาใดถูกดำเนินการ คลาสใดถูกโหลด หลังจากสะสมข้อมูลได้เพียงพอ (ปกติหลังจาก 2–3 ครั้งของการรันแอปพลิเคชัน) ART จะเรียกใช้ dex2oat ในพื้นหลังและคอมไพล์เฉพาะ hot-methods ที่ถูกทำโปรไฟล์ เป็นโค้ดเนทีฟ
ART รองรับหลายโหมดการคอมไพล์ที่ควบคุมผ่าน system_server โหมด "speed" คอมไพล์ทุกเมธอดเป็น AOT (ประสิทธิภาพสูงสุด ติดตั้งนาน) โหมด "speed-profile" คอมไพล์เฉพาะ hot-methods ที่ถูกทำโปรไฟล์ (สมดุลระหว่างความเร็วและขนาด) โหมด "verify" ตรวจสอบ byte-code เท่านั้นโดยไม่คอมไพล์ (ใช้พื้นที่น้อยที่สุด แปลความหมาย) โดยค่าเริ่มต้นจะใช้ speed-profile — เหมาะสมที่สุดสำหรับแอปพลิเคชันส่วนใหญ่
| โหมด | การคอมไพล์ | เวลาในการติดตั้ง | ประสิทธิภาพ |
|---|---|---|---|
| speed | AOT เต็มรูปแบบ | นาน | สูงสุด |
| speed-profile | AOT แบบทำโปรไฟล์ | เร็ว | สูง |
| verify | ไม่มีการคอมไพล์ | ทันที | แปลความหมาย |
| space | AOT ขั้นต่ำ | ปานกลาง | ปานกลาง |
โปรไฟเลอร์ รวบรวมข้อมูลการทำงานลงในไฟล์ .prof เฉพาะ แต่ละแอปพลิเคชันเก็บโปรไฟล์ของตนเองใน /data/misc/profiles/ เมื่อถึงเกณฑ์ที่กำหนด (ปกติ 1,000 ตัวอย่าง) โปรไฟเลอร์จะเรียกใช้ dex2oat เพื่อคอมไพล์ hot-methods ที่ตรวจพบ โปรไฟล์จะถูกเก็บไว้ระหว่างการอัปเดตแอปพลิเคชัน ซึ่งช่วยเร่งการปรับแต่งใหม่หลังการอัปเดต OTA ของระบบ
การเก็บขยะ ใน ART ได้รับการปรับปรุงอย่างมากเมื่อเทียบกับ Dalvik แทนที่จะใช้ Concurrent Mark and Sweep (CMS) แบบเธรดเดียว ART ใช้ตัวเก็บขยะแบบเจเนอเรชันพร้อมการเพิ่มประสิทธิภาพหลายอย่าง: moving collector (การอัดแน่นฮีป), large object space (การจัดเก็บวัตถุขนาดใหญ่แยกต่างหาก) และ concurrent compaction (การอัดแน่นแบบขนาน)
การหยุดชั่วคราวของ GC ทั่วไปใน ART คือ 2–3 ms เทียบกับ 5–10 ms ใน Dalvik ซึ่งเป็นไปได้ด้วยกลไกหลายอย่าง ประการแรก ART ใช้ read-barrier แทน stop-the-world สำหรับเฟส concurrent ประการที่สอง ตัวเก็บขยะแบบเจเนอเรชันจะประมวลผลเฉพาะวัตถุเจเนอเรชันใหม่ในรอบส่วนใหญ่ โดยไม่กระทบทั้งฮีป ประการที่สาม large object space (LOS) ถูกจัดสรรแยกต่างหากและไม่มีส่วนร่วมในรอบ GC ปกติ
// การเปิดใช้งานบันทึก GC เพื่อดีบัก
System.logV("ART", "GC trigger: allocation failed");
// การเรียก GC แบบบังคับ (ไม่แนะนำในโปรดักชัน)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Debug.getRuntimeIStats();
}
แม้จะมี GC ที่ดีขึ้น การรั่วไหลของหน่วยความจำ ยังคงเป็นปัญหาที่เกี่ยวข้อง สาเหตุเฉพาะของ ART คือการโหลดไลบรารีเนทีฟผ่าน JNI โดยไม่ปล่อยอย่างถูกต้อง หากโค้ดเนทีฟจัดสรรหน่วยความจำผ่าน malloc แต่ไม่เรียกใช้ free ART ไม่สามารถคืนหน่วยความจำนี้ได้ — เนื่องจากอยู่นอกฮีปที่จัดการ เครื่องมือ AddressSanitizer ใน Android NDK ช่วยตรวจจับการรั่วไหลดังกล่าว
ART และ Dalvik เป็นการนำไปใช้ที่แตกต่างกันโดยพื้นฐานของงานเดียวกัน: การทำงานของแอปพลิเคชัน Android ความแตกต่างส่งผลกระทบทุกระดับ: ตั้งแต่การคอมไพล์จนถึงการจัดการหน่วยความจำ ด้านล่างนี้คือการเปรียบเทียบตามพารามิเตอร์สำคัญของประสิทธิภาพและความเข้ากันได้
ข้อได้เปรียบหลักของ ART คือ การขจัดการอุ่นเครื่อง JIT บน Dalvik แอปพลิเคชันอาจช้าในช่วง 3–10 วินาทีแรกในขณะที่ JIT คอมไพล์ hot-methods บน ART เมธอดทั้งหมดถูกคอมไพล์เป็นโค้ดเนทีฟแล้ว (หรือจะถูกคอมไพล์ในพื้นหลัง) ซึ่งเห็นได้ชัดเจนโดยเฉพาะในเกมและแอปพลิเคชันที่มี UI หนัก: ความแตกต่างของ fps อาจสูงถึง 15–20% ในทางที่เป็นประโยชน์ต่อ ART
| พารามิเตอร์ | Dalvik | ART |
|---|---|---|
| การคอมไพล์ | JIT (ระหว่างทำงาน) | AOT + ไฮบริด (เมื่อติดตั้ง) |
| เวลาเริ่มต้น | 3–10 วิ (อุ่นเครื่อง) | ทันที |
| ขนาด APK | ~6–7 MB (DEX) | +20% (OAT) |
| การหยุดของ GC | 5–10 ms | 2–3 ms |
| การใช้พลังงาน | สูงกว่า (JIT ทำให้ CPU ร้อน) | ต่ำกว่า (โค้ดเนทีฟ) |
แอปพลิเคชันทั้งหมดที่เขียนสำหรับ Dalvik ทำงานบน ART ได้โดยไม่ต้องเปลี่ยนแปลง Google รับประกันความเข้ากันได้ย้อนหลังอย่างสมบูรณ์ในระดับ DEX byte-code ข้อยกเว้นคือโค้ดที่ใช้ Dalvik-specific internal API ผ่านรีเฟลกชัน: สมาชิกคลาสของ dalvik.system.DexFile ที่ถูกทำเครื่องหมาย @hide ใน Android SDK โค้ดดังกล่าวควรอัปเดตเพื่อใช้ public API
ART กลายเป็นสภาพแวดล้อมรันไทม์แรกของ Android ที่รองรับฟีเจอร์ Java 8 โดยกำเนิด ตั้งแต่ Android 7.0 ART รวมดีซูการ์ริ่ง — กระบวนการแปลงโครงสร้าง Java 8 (แลมบ์ดา, method references, Stream API) เป็นโค้ด Java 7 ที่เทียบเท่า ซึ่งช่วยให้ใช้ไวยากรณ์สมัยใหม่ได้โดยไม่สูญเสียความเข้ากันได้กับอุปกรณ์รุ่นเก่า
ดีซูการ์ริ่งดำเนินการโดยคอมไพเลอร์ D8 และทำงานดังนี้ โค้ดต้นฉบับที่มีแลมบ์ดาจะถูกแปลงเป็นเมธอดสังเคราะห์ภายในคลาสเดียวกัน และแลมบ์ดาจะถูกแทนที่ด้วยการเรียก invoke-custom รันไทม์ของ ART รวมการรองรับคำสั่ง invoke-custom ซึ่งเพิ่มเข้ามาโดยเฉพาะสำหรับ Java 8 บนอุปกรณ์ที่ใช้ Android 6.0 และต่ำกว่า แลมบ์ดาจะถูกดีซูการ์เป็นคลาสนิรนาม
// แลมบ์ดา Java 8 — ดีซูการ์ริ่งใน ART
button.setOnClickListener(v -> handleClick(v));
// หลังจากดีซูการ์ริ่ง (เทียบเท่ากับ Java 7)
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handleClick(v);
}
});
ไม่ใช่ทุกฟีเจอร์ Java 8 ที่รองรับดีซูการ์ริ่ง java.time API (วันที่และเวลา) สามารถใช้งานได้ผ่าน desugar_jdk_libs เท่านั้น — ไลบรารีเพิ่มเติมที่เพิ่มใน build.gradle Stream API ก็ต้องใช้ desugar_jdk_libs เช่นกัน java.util.function และ Optional ทำงานได้โดยไม่ต้องมีการพึ่งพาเพิ่มเติม การรองรับ Java 8 อย่างเต็มรูปแบบมีให้บนอุปกรณ์ที่ใช้ Android 8.0 ขึ้นไปโดยไม่ต้องดีซูการ์ริ่ง
แม้ว่า ART จะเข้ากันได้ย้อนหลัง แต่แนวปฏิบัติในการปรับแต่งบางอย่างช่วยเพิ่มประสิทธิภาพบนสภาพแวดล้อมนี้โดยเฉพาะ คำแนะนำหลักคือลดรีเฟลกชันให้น้อยที่สุด ART คอมไพล์เมธอดที่มองเห็นได้ในขั้นตอนการคอมไพล์เป็นการเรียกโค้ดเครื่องโดยตรง รีเฟลกชัน บังคับให้ ART สร้าง stubs เพิ่มเติม ซึ่งทำให้การทำงานช้าลง 10–15%
ตั้งแต่ Android 9.0 ART มีการรองรับ App Startup Optimization นักพัฒนาสามารถทำเครื่องหมายคลาสการเริ่มต้นในแมนิเฟสต์ผ่าน <initialization> และ ART จะโหลดคลาสเหล่านั้นล่วงหน้าเมื่อเริ่มต้นแอปพลิเคชัน ซึ่งช่วยลดเวลาเริ่มต้นลง 5–15% สำหรับแอปพลิเคชันที่มีปลั๊กอินหรือไลบรารีจำนวนมาก
<!-- App Startup Optimization ใน AndroidManifest.xml -->
<application>
<profileable
android:shell="true"
android:enable="true" />
</application>
สำหรับการวัดประสิทธิภาพบน ART ให้ใช้ systrace และ perfetto Systrace แสดงเวลาในการคอมไพล์ของ dex2oat ความถี่ของ GC และความเร็วในการเรนเดอร์เฟรม Perfetto ให้ข้อมูลที่ละเอียดมากขึ้น: การกระจายเธรด เวลาการเปลี่ยน JNI การโหลดไลบรารีเนทีฟ การเรียกใช้: adb shell perfetto -o /data/misc/perfetto-traces/trace.perfetto -t 10s sched freq idle am wm
คำถามที่พบบ่อย
ART (Android Runtime) — คือสภาพแวดล้อมรันไทม์ของแอปพลิเคชัน Android ที่คอมไพล์โค้ดของแอปพลิเคชันเป็นโค้ดเครื่องเมื่อติดตั้ง ซึ่งช่วยเร่งการเริ่มต้นและการทำงานของแอปพลิเคชันเมื่อเทียบกับสภาพแวดล้อม Dalvik รุ่นเก่า
ART คอมไพล์โค้ดล่วงหน้า (AOT) เมื่อติดตั้งแอปพลิเคชัน ในขณะที่ Dalvik คอมไพล์โค้ดเป็นส่วนๆ ระหว่างการทำงาน (JIT) ดังนั้นบน ART แอปพลิเคชันเริ่มทำงานเร็วขึ้นและใช้พลังงานน้อยลง
รัน adb shell getprop และค้นหาพร็อพเพอร์ตี้ persist.sys.dalvik.vm.lib.2 ค่า "libart.so" หมายถึง ART, "libdvm.so" หมายถึง Dalvik บนอุปกรณ์ทั้งหมดที่ใช้ Android 5.0+ สภาพแวดล้อมรันไทม์คือ ART
เพียงเล็กน้อย ตัวแอปพลิเคชันยังคงอยู่ในรูปแบบ APK พร้อมไฟล์ DEX ART สร้างไฟล์ OAT เพิ่มเติมใน /data/dalvik-cache/ ซึ่งใช้พื้นที่มากกว่า DEX ดั้งเดิม 10–20% แต่พื้นที่จัดเก็บนี้ไม่รวมอยู่ในขนาด APK
ใช่ ART รองรับฟีเจอร์ Java 8 ส่วนใหญ่ผ่านกลไกดีซูการ์ริ่ง แลมบ์ดา, method references และฟังก์ชันนัลอินเทอร์เฟซทำงานบนอุปกรณ์ทั้งหมดที่ใช้ Android 5.0+ สำหรับ Stream API และ java.time ต้องใช้ไลบรารี desugar_jdk_libs
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม