Runtime คือชั้นซอฟต์แวร์ที่จัดการการทำงานของโค้ดแอปพลิเคชันมือถือ: จัดสรรหน่วยความจำ จัดการข้อยกเว้น เรียกใช้ garbage collection และจัดส่งการเรียกเมธอด หากไม่มี runtime จะไม่มีแอปพลิเคชันใดสามารถทำงานได้ — มันคือชั้นกลางระหว่างโค้ดที่คอมไพล์แล้วและระบบปฏิบัติการ ตาม Android Developer Documentation, 2025 สภาพแวดล้อมรันไทม์เป็นองค์ประกอบสำคัญของแพลตฟอร์มที่กำหนดประสิทธิภาพและความเข้ากันได้
ประเด็นสำคัญ
Runtime คือโครงสร้างพื้นฐานที่รับประกันการทำงานของโปรแกรมหลังจากที่มันเริ่มทำงาน ในบริบทของการพัฒนาแอปมือถือ runtime รวมถึงตัวโหลดคลาส ตัวจัดสรรหน่วยความจำ ตัวเก็บขยะ ตัวจัดส่งเมธอดและตัวจัดการข้อยกเว้น หากไม่มีชั้นกลางนี้ ระบบปฏิบัติการไม่สามารถทำงานไบต์โค้ด Dalvik หรือข้อความ Objective-C ได้
แพลตฟอร์มมือถือใช้การใช้งาน runtime ที่แตกต่างกัน Android ใช้ ART (Android Runtime) ด้วยการคอมไพล์แบบผสม AOT/JIT iOS ใช้ Objective-C Runtime — ระบบไดนามิกที่อิงตามการส่งข้อความและตัวระบุ SEL ทั้งสองแนวทางแก้ปัญหาเดียวกัน: ทำงานโค้ดของนักพัฒนาบนอุปกรณ์เฉพาะด้วยประสิทธิภาพสูงสุด
ตาม Google I/O 2024 Android Runtime ประมวลผลมากกว่า 10 พันล้านเมธอดต่อวันบนอุปกรณ์ทั่วโลก ประสิทธิภาพของ runtime ส่งผลโดยตรงต่อความเร็วในการเริ่มต้นแอปพลิเคชัน ความลื่นไหลของแอนิเมชันและการใช้แบตเตอรี่ ทุกการเรียกเมธอด ทุกการจัดสรรหน่วยความจำและทุกรอบการเก็บขยะผ่านชั้น runtime
ระบบ runtime ประกอบด้วยองค์ประกอบหลักห้าอย่าง: ตัวโหลดคลาส ตัวจัดการหน่วยความจำ ตัวแปลหรือคอมไพเลอร์ ตัวจัดส่งเมธอดและระบบรักษาความปลอดภัย แต่ละองค์ประกอบทำหน้าที่ที่กำหนดอย่างเคร่งครัดในกระบวนการทำงานของโค้ด
เมื่อผู้ใช้เริ่มแอปพลิเคชัน ClassLoader โหลดไฟล์ DEX (Android) หรือไบนารี Mach-O (iOS) เข้าไปใน RAM ใน Android ขั้นตอนนี้รวมถึงการตรวจสอบไบต์โค้ด: runtime ตรวจสอบว่าโค้ดไม่มีคำสั่งที่ไม่ปลอดภัย ไม่เกินขอบเขตอาเรย์และปฏิบัติตามชนิดข้อมูล การตรวจสอบเป็นขั้นตอนความปลอดภัยที่สำคัญที่ป้องกันการทำงานของโค้ดที่เป็นอันตราย
ตัวจัดการหน่วยความจำ จัดสรรและปล่อยหน่วยความจำสำหรับออบเจ็กต์ ใน Android ART ใช้ตัวเก็บขยะแบบพร้อมกัน (concurrent) กับการเก็บแบบรุ่น (generational collection): ออบเจ็กต์อายุน้อยถูกตรวจสอบบ่อยกว่า ออบเจ็กต์อายุมากถูกตรวจสอบน้อยกว่า Objective-C Runtime ใช้ Automatic Reference Counting (ARC) ซึ่งคอมไพเลอร์แทรกการเรียก retain/release โดยอัตโนมัติ
ตัวจัดส่งเมธอด กำหนดว่าการใช้งานเมธอดใดจะถูกเรียก ในภาษาสแตติก (Kotlin, Swift) การจัดส่งทำผ่าน vtable — ตารางเมธอดเสมือน ในภาษาไดนามิก (Objective-C) ข้อความผ่าน objc_msgSend ซึ่งค้นหาการใช้งานในคลาสและคลาสแม่ของมัน ผลลัพธ์ถูกเก็บไว้ในแคช method cache เพื่อเร่งการเรียกซ้ำ
Android Runtime (ART) คือเครื่องเสมือนที่ทำงานไบต์โค้ด DEX ของแอปพลิเคชัน Android ART แทนที่ Dalvik ใน Android 5.0 Lollipop โดยแนะนำการคอมไพล์ AOT: แอปพลิเคชันถูกคอมไพล์เป็นโค้ดเครื่องครั้งเดียวระหว่างการติดตั้ง สิ่งนี้กำจัดโอเวอร์เฮดของการคอมไพล์ JIT ทุกครั้งที่เริ่ม
ตั้งแต่ Android 7.0 Nougat ART ใช้แนวทางแบบผสม ระหว่างการติดตั้ง การคอมไพล์ JIT จะดำเนินการเฉพาะสำหรับเมธอดที่ใช้บ่อย (hot methods) ส่วนโค้ดที่เหลือถูกแปล โปรเซสพื้นหลัง (profile-guided optimization) วิเคราะห์ว่าเมธอดใดถูกเรียกบ่อยที่สุดและคอมไพล์ AOT ในช่วงเวลาที่อุปกรณ์ว่าง สิ่งนี้ลดเวลาในการติดตั้งในขณะที่รับประกันประสิทธิภาพสูง
ART ยังรวมถึง คอมไพเลอร์ AOT (dex2oat) ที่แปลงไฟล์ DEX เป็นไบนารี ELF ด้วยโค้ดเครื่อง ARM64 การคอมไพล์ดำเนินการด้วยระดับการปรับให้เหมาะสมสามระดับ: quicken (เร็ว), optimize (ปานกลาง) และ everything (สมบูรณ์) โดยค่าเริ่มต้น Android ใช้ optimize ซึ่งสร้างสมดุลระหว่างความเร็วในการคอมไพล์และประสิทธิภาพของโค้ด
class RuntimeExample {
fun measureExecutionTime() {
val start = System.nanoTime()
// การเรียกเมธอดที่คอมไพล์โดย ART
processData()
val end = System.nanoTime()
println("เวลาดำเนินการ: ${end - start} ns")
}
}
ในตัวอย่างด้านบน System.nanoTime() เป็นเมธอดเนทีฟซึ่งการเรียกถูกจัดส่งผ่าน ART runtime ไปยังเคอร์เนล Linux ART แปลงไบต์โค้ด Kotlin เป็นคำสั่ง ARM64 ที่ทำงานโดยโปรเซสเซอร์ของอุปกรณ์ กระบวนการนี้เกิดขึ้นอย่างโปร่งใสสำหรับนักพัฒนา แต่การปรับให้เหมาะสมเป็นงานสำคัญของทีม Android Platform
Profile-guided optimization เป็นกลไกของ ART ที่รวบรวมโปรไฟล์การใช้งานเมธอด ไฟล์ profiles/
นักพัฒนาสามารถเปิดใช้งาน baseline profiles ในโปรเจกต์ Gradle ของตน สิ่งเหล่านี้เป็นคำอธิบายประกอบด้วยตนเองที่บอก ART ว่าเมธอดใดควรคอมไพล์ AOT ทันทีหลังจากติดตั้ง Baseline profiles ลดการเริ่มครั้งแรกลง 40% โดยไม่ต้องรอการสร้างโปรไฟล์พื้นหลัง
Objective-C Runtime คือไลบรารีไดนามิกที่ให้การทำงานของโค้ด Objective-C บน iOS และ macOS แกนกลางของมันคือฟังก์ชัน objc_msgSend ซึ่งใช้การส่งข้อความ: แทนที่จะเรียกเมธอดโดยตรง ออบเจ็กต์ส่งข้อความพร้อมตัวเลือก (selector) และ runtime กำหนดว่าการใช้งานใดควรทำงาน
แต่ละออบเจ็กต์ Objective-C มีพอยน์เตอร์ isa ไปยังคลาสของมัน และคลาสมี dispatch table ที่จับคู่ตัวเลือก (SEL) กับการใช้งาน (IMP) เมื่อเมธอดถูกเรียก objc_msgSend เดินทางตามลำดับโซ่: คลาส → คลาสแม่ → NSObject จนกว่าจะพบ IMP หากไม่พบการใช้งาน runtime จะเรียกกลไกการส่งต่อ (forwarding mechanism) ซึ่งสามารถสกัดกั้นข้อความหรือสร้างข้อยกเว้น
Objective-C Runtime ยังรองรับ method swizzling — การแทนที่ IMP ของตัวเลือกที่มีอยู่ในขณะทำงาน นี่เป็นกลไกที่ทรงพลังที่ใช้ในไลบรารี AOP และเครื่องมือตรวจสอบ แต่ต้องใช้ความระมัดระวังเนื่องจากผลกระทบต่อทั้งแอปพลิเคชัน
@interface RuntimeDemo : NSObject
- (void)printClassInfo;
@end
@implementation RuntimeDemo
- (void)printClassInfo {
// objc_getClass — ฟังก์ชัน runtime
Class cls = objc_getClass("RuntimeDemo");
unsigned int count;
Method *methods = class_copyMethodList(cls, &count);
NSLog("จำนวนเมธอด: %d", count);
}
@end
โค้ดแสดงการเข้าถึงโดยตรงไปยัง Objective-C Runtime API: objc_getClass รับออบเจ็กต์คลาสตามชื่อ class_copyMethodList ดึงรายการของเมธอดทั้งหมด นี่คือ reflection ในการทำงาน — การเข้าถึงเมทาดาทาของคลาสในขณะทำงาน แนวทางนี้ใช้ใน XCTest สำหรับการลงทะเบียนทดสอบแบบไดนามิก
พอยน์เตอร์ isa คือพอยน์เตอร์ไปยังคลาสของออบเจ็กต์ที่เก็บไว้ใน 8 ไบต์แรกของแต่ละออบเจ็กต์ ตั้งแต่ iOS 12 Apple ได้นำ isa-swizzling มาใช้เพื่อการปรับให้เหมาะสม: บิตล่างของ isa เข้ารหัสข้อมูลเพิ่มเติมเกี่ยวกับสถานะของออบเจ็กต์ Tagged pointers เป็นการปรับให้เหมาะสมอีกแบบหนึ่งที่ค่าสูงถึง 60 บิต (NSNumber, NSDate) ถูกเก็บไว้โดยตรงในพอยน์เตอร์ โดยไม่ต้องจัดสรรออบเจ็กต์ในฮีป สิ่งนี้ลดภาระของตัวจัดการหน่วยความจำลง 30%
JIT (Just-In-Time) และ AOT (Ahead-Of-Time) เป็นสองแนวทางในการคอมไพล์ไบต์โค้ดเป็นโค้ดเครื่อง JIT คอมไพล์โค้ดระหว่างการทำงานของแอปพลิเคชัน วิเคราะห์จุดร้อนและปรับให้เหมาะสมทันที AOT คอมไพล์โค้ดทั้งหมดล่วงหน้า — ระหว่างการติดตั้งแอปพลิเคชันหรือฝั่งนักพัฒนา
| คุณลักษณะ | JIT | AOT |
|---|---|---|
| เวลาคอมไพล์ | ระหว่างการทำงาน | ระหว่างการติดตั้ง/สร้าง |
| ขนาด APK/IPA | เล็กกว่า (ไบต์โค้ดเท่านั้น) | ใหญ่กว่า (โค้ดเครื่อง) |
| ความเร็วเริ่มต้น | ต่ำกว่า (ต้องการการคอมไพล์) | สูงกว่า (โค้ดพร้อมทำงาน) |
| การปรับให้เหมาะสมเฉพาะอุปกรณ์ | ใช่ (ปรับตัวได้) | จำกัด (ทั่วไป) |
| การใช้ RAM | สูงกว่า (คอมไพเลอร์ในหน่วยความจำ) | ต่ำกว่า |
แนวทางผสมของ ART (Android 7+) ถือว่าเหมาะสมที่สุด: แอปพลิเคชันใช้ตัวแปลสำหรับเมธอดที่ถูกเรียกน้อย JIT สำหรับ hot methods และ AOT สำหรับเมธอดจาก profile-guided optimization iOS ในทางตรงกันข้าม ใช้ AOT ที่เข้มงวดผ่าน LLVM: Swift และ Objective-C ถูกคอมไพล์เป็นโค้ดเครื่องในขั้นตอนการสร้างใน Xcode
ตาม Apple Developer Documentation, 2024 Swift runtime เพิ่มประมาณ 15 MB ให้กับขนาดแอปพลิเคชัน Flutter ใช้ Dart VM ของตัวเอง โดยที่การคอมไพล์ JIT ทำงานในโหมดดีบักสำหรับ hot reload และ AOT ในโหมดรีลีสสำหรับประสิทธิภาพสูงสุด React Native ใช้ Hermes — เครื่องยนต์ JavaScript พร้อมการคอมไพล์ AOT ที่ลดเวลาเริ่มต้นลง 50%
ARM64 Runtime คือระดับที่โค้ดเครื่องโต้ตอบกับโปรเซสเซอร์ของอุปกรณ์ อุปกรณ์มือถือสมัยใหม่ส่วนใหญ่ทำงานบนโปรเซสเซอร์ ARM64 (aarch64) Runtime แปลไบต์โค้ดหรือการเรียกเนทีฟเป็นคำสั่ง ARM64 ที่ CPU ทำงาน
รีจิสเตอร์ ARM64 หลักที่ใช้โดย runtime: x0–x7 (พารามิเตอร์ฟังก์ชัน), x8 (ผลลัพธ์ทางอ้อม), x30 (ที่อยู่ส่งกลับ), sp (พอยน์เตอร์สแต็ก), fp (พอยน์เตอร์เฟรม) ART สร้างโค้ดที่ปฏิบัติตาม ARM64 Procedure Call Standard: การเรียกเมธอดทั้งหมดผ่านโปรโตคอลที่กำหนดโดยสถาปัตยกรรมโปรเซสเซอร์
การเข้าใจ ARM64 ABI สำคัญสำหรับการปรับให้เหมาะสมด้านประสิทธิภาพ: inline caching, branch prediction และการจัดตำแหน่งโค้ดในหน่วยความจำส่งผลโดยตรงต่อความเร็วของ runtime เครื่องมือสร้างโปรไฟล์ (Android Studio Profiler, Instruments) แสดงว่าส่วนโค้ดใดใช้เวลามากที่สุดใน runtime — การปรับให้เหมาะสมกับส่วนเหล่านี้ให้การปรับปรุงมากที่สุด
// ตัวอย่าง ARM64 assembly ที่สร้างโดย ART
// การเรียกเมธอดที่มีสองพารามิเตอร์
mov x0, x23 // self (this)
mov x1, x24 // param1
mov x2, x25 // param2
bl methodEntryPoint // เรียกผ่าน runtime
str x0, [sp, #8] // บันทึกผลลัพธ์
ในตัวอย่างนี้ คำสั่ง ARM64 mov ส่งอาร์กิวเมนต์ไปยังรีจิสเตอร์ x0–x2 bl เรียกจุดเริ่มต้นของเมธอด และ str เก็บค่าส่งกลับ Runtime สร้างคำสั่งดังกล่าวสำหรับทุกการเรียกเมธอด ปรับลำดับให้เหมาะสมผ่าน devirtualization และ inlining
Runtime โอเวอร์เฮด คือราคาที่หลีกเลี่ยงไม่ได้ของการจัดส่งแบบไดนามิก แต่ละการเรียกเมธอดผ่าน runtime ต้องการ: ค้นหาการใช้งานใน dispatch table, ตรวจสอบชนิด, เรียก IMP และส่งคืนผลลัพธ์ การวัดแสดงว่า runtime เพิ่ม 10–50 ns ต่อการเรียกใน Objective-C และ 5–20 ns ใน ART
เพื่อลดโอเวอร์เฮด นักพัฒนาใช้ monomorphic inlining (ART) และ method caching (Objective-C) Kotlin/Native และ Swift คอมไพล์ตรงไปยัง ARM64 กำจัดชั้น runtime โดยสมบูรณ์ แต่สูญเสียความสามารถแบบไดนามิก — reflection, swizzling, การโหลดคลาสแบบไดนามิก
คำถามที่พบบ่อย
SDK (Software Development Kit) คือชุดเครื่องมือสำหรับการพัฒนาแอปพลิเคชัน (คอมไพเลอร์ ไลบรารี ยูทิลิตี้) Runtime คือสภาพแวดล้อมที่แอปพลิเคชันที่พัฒนาแล้วทำงานบนอุปกรณ์ นักพัฒนาต้องการ SDK ผู้ใช้ต้องการ runtime
ไม่ — runtime เป็นส่วนหนึ่งของระบบปฏิบัติการและไม่สามารถถูกเปลี่ยนโดยผู้ใช้ ART ถูกสร้างไว้ใน Android Framework Objective-C Runtime ใน iOS นักพัฒนาสามารถเลือกภาษา (Kotlin/Native โดยไม่มี runtime) หรือใช้เครื่องเสมือนเช่น Dart VM ใน Flutter
ใช่ runtime ส่งผลต่อการใช้พลังงาน การเก็บขยะ ใน ART และ Swift runtime ใช้ CPU ซึ่งเพิ่มการใช้แบตเตอรี่ การปรับให้เหมาะสมเช่น concurrent GC และ tagged pointers ใน iOS ลดผลกระทบของ runtime ต่อแบตเตอรี่ลง 20–30%
Runtime error คือข้อผิดพลาดที่เกิดขึ้นระหว่างการทำงาน: null pointer exception, index out of bounds, การหารด้วยศูนย์ ต่างจากข้อผิดพลาดขณะคอมไพล์ มันไม่ถูกตรวจพบระหว่างการสร้าง ตรวจจับผ่านบล็อก try-catch หรือการรายงานข้อขัดข้อง (Firebase Crashlytics, Sentry)
Swift runtime เบากว่า Objective-C: มันไม่รองรับการจัดส่งแบบไดนามิกโดยค่าเริ่มต้น ใช้ value types (struct) โดยไม่ต้องจัดสรรในฮีปและไม่มี message forwarding เมธอด Swift ถูกเรียกโดยตรงผ่าน vtable เว้นแต่จะถูกทำเครื่องหมาย @objc dynamic สิ่งนี้ให้การปรับปรุงความเร็วสูงถึง 5 เท่าในการวัดประสิทธิภาพ
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม