JIT: การคอมไพล์แบบ Just-In-Time คืออะไรและทำงานอย่างไร

ผู้แต่ง: IT Sectr เผยแพร่เมื่อ: 2026-04-16 เวลาอ่าน: 9 นาที

JIT (Just-In-Time) เป็นเทคโนโลยีการคอมไพล์แบบไดนามิกที่แปลงไบต์โค้ดหรือตัวแทนกลางของโปรแกรมเป็นคำสั่งเครื่องโดยตรงระหว่างการทำงาน ใน Android คอมไพเลอร์ JIT ปรากฏครั้งแรกในเวอร์ชัน 2.2 Froyo ซึ่งเป็นส่วนหนึ่งของเครื่องเสมือน Dalvik และเพิ่มความเร็วในการทำงานของแอปพลิเคชัน 2–5 เท่า ตามข้อมูลของ Google, 2024 JIT สมัยใหม่ใน ART ผสานการแปลความหมายกับการคอมไพล์แบบมีโปรไฟล์ของเมธอดร้อน

ประเด็นสำคัญ

  • JIT — การคอมไพล์แบบ Just-In-Time: การแปลงโค้ดเป็นโค้ดเครื่องโดยตรงขณะโปรแกรมกำลังทำงาน
  • ใน Dalvik, JIT คอมไพล์ เมธอดร้อน หลังจากเกินเกณฑ์การเรียก (~200 ครั้ง)
  • JIT ลดเวลาการติดตั้งและใช้พื้นที่น้อยกว่า การคอมไพล์ AOT แบบเต็ม
  • ข้อเสียหลักคือ ความล่าช้าในการอุ่นเครื่อง: ในวินาทีแรกแอปพลิเคชันทำงานช้าลง
  • ใน ART สมัยใหม่ JIT ถูกใช้ในโหมดไฮบริดร่วมกับ การเพิ่มประสิทธิภาพ AOT ในพื้นหลัง

การคอมไพล์ JIT คืออะไร?

Just-In-Time (JIT) เป็นวิธีการคอมไพล์ที่ซอร์สโค้ดหรือไบต์โค้ดถูกแปลงเป็นคำสั่งเครื่องไม่ใช่ล่วงหน้า (เหมือนกับ AOT) แต่ในขณะที่มีการเรียกส่วนที่เกี่ยวข้องของโปรแกรมครั้งแรก คำว่า “Just-In-Time” หมายถึงการคอมไพล์เกิดขึ้น “ทันเวลา” — ทันทีก่อนการทำงาน

แนวคิดของ JIT มีมาตั้งแต่ทศวรรษ 1960 แต่ได้รับการยอมรับอย่างกว้างขวางกับการถือกำเนิดของ Java Virtual Machine ในปี 1995 JIT ช่วยให้สามารถรวมการพกพาของไบต์โค้ด (เขียนครั้งเดียว — ทำงานได้ทุกที่) เข้ากับประสิทธิภาพที่ใกล้เคียงกับโค้ดพื้นเมือง ใน Java HotSpot VM คอมไพเลอร์ JIT วิเคราะห์โค้ดที่ทำงานและคอมไพล์เฉพาะส่วนที่สำคัญที่สุด ประหยัดเวลาและหน่วยความจำ

หลักการทำงาน

คอมไพเลอร์ JIT รับไบต์โค้ดเป็นอินพุต แปลความหมาย และรวบรวมสถิติไปพร้อมกัน เมื่อส่วนของโค้ด (เมธอด, ลูป) ถูกเรียกบ่อยเพียงพอ JIT จะตัดสินใจคอมไพล์มัน โค้ดเครื่องที่คอมไพล์แล้วจะถูกเก็บในแคช — ในการเรียกครั้งถัดไป จะใช้เวอร์ชันที่คอมไพล์แล้ว ซึ่งให้ความเร็วโดยไม่ต้องคอมไพล์ทั้งโปรแกรม

java
// ตัวอย่าง: เมธอดจะกลายเป็นร้อนหลังจากการเรียกหลายครั้ง
public class HotMethod {
    private int compute(int n) {
        int sum = 0;
        for (int i = 0; i < n; i++) {
            sum += i * i;
        }
        return sum;
    }
}

// เรียก 500 ครั้งในลูป — JIT จะคอมไพล์ compute
for (int t = 0; t < 500; t++) {
    hot.compute(1000);
}

JIT ใน Android: Dalvik และ ART

ใน Android การคอมไพล์ JIT ผ่านสามช่วงของวิวัฒนาการ ช่วงแรก — Dalvik ที่ไม่มี JIT (Android 1.0–2.1): การแปลความหมายบริสุทธิ์ของไบต์โค้ด DEX ช่วงที่สอง — Dalvik ที่มี JIT (Android 2.2–4.4): การเปิดตัวคอมไพเลอร์ JIT ซึ่งเพิ่มความเร็วแอปพลิเคชัน 2–5 เท่า ช่วงที่สาม — ART ที่มี JIT แบบไฮบริด (Android 7.0+): การกลับมาของ JIT ในความสามารถใหม่

JIT ใน Dalvik ถูกนำมาใช้เป็นคอมไพเลอร์ แบบร่องรอย มันไม่ได้วิเคราะห์เมธอดแต่ละเมธอด แต่เป็นลูกโซ่ของคำสั่ง (ร่องรอย) ที่ทำงานตามลำดับบ่อยครั้ง สิ่งนี้ช่วยให้สามารถคอมไพล์เส้นทางการทำงานทั้งหมด รวมถึงหลายเมธอด วิธีการนี้มีประสิทธิภาพสำหรับ โปรเซสเซอร์มือถือ ที่มีแคชคำสั่งขนาดเล็ก เนื่องจากร่องรอยที่คอมไพล์แล้วพอดีกับแคช L1

JIT ใน ART สมัยใหม่

เริ่มตั้งแต่ Android 7.0 Nougat, ART ใช้ JIT แบบเมธอด — มันคอมไพล์เมธอดแต่ละเมธอดตามโปรไฟล์การทำงาน JIT นี้ทำงานเร็วกว่า Dalvik JIT อย่างมาก: เวลาคอมไพล์ทั่วไปสำหรับหนึ่งเมธอดคือ 0.5–1 มิลลิวินาที เทียบกับ 3–5 มิลลิวินาทีใน Dalvik โค้ดที่คอมไพล์แล้วถูกเก็บในพื้นที่หน่วยความจำแยกต่างหาก (แคชโค้ด JIT) แทนที่จะอยู่ในฮีปของแอปพลิเคชัน ซึ่งลดการกระจายตัว

พารามิเตอร์Dalvik JITART JIT
ประเภทแบบร่องรอยแบบเมธอด
ความเร็วในการคอมไพล์3–5 มิลลิวินาที/เมธอด0.5–1 มิลลิวินาที/เมธอด
เกณฑ์การคอมไพล์~200 การเรียกไดนามิก
แคชโค้ดในฮีปแอปพลิเคชันแคชโค้ด JIT
การทำโปรไฟล์ภายในไฟล์ .prof ภายนอก

การตรวจจับเมธอดร้อนและเกณฑ์การคอมไพล์

กลไกหลักของ JIT คือ การตรวจจับเมธอดร้อน ทุกครั้งที่เรียกเมธอดจะเพิ่มตัวนับภายใน เมื่อตัวนับข้ามเกณฑ์ เมธอดจะถูกทำเครื่องหมายเป็น “ร้อน” และส่งไปคอมไพล์ ใน Dalvik เกณฑ์ถูกกำหนดตายตัว (~200 การเรียก) ใน ART ตัวนับถูกกำหนดแบบไดนามิกขึ้นอยู่กับทรัพยากรที่มีของอุปกรณ์

กระบวนการคอมไพล์ประกอบด้วยหลายขั้นตอน ขั้นแรก — การวิเคราะห์ไบต์โค้ด: JIT ตรวจสอบสตรีมคำสั่งและสร้างกราฟการไหลของข้อมูล ขั้นที่สอง — การเพิ่มประสิทธิภาพ: การอินไลน์เมธอดเล็ก การกำจัดโค้ดที่ตายแล้ว การพับค่าคงที่ ขั้นที่สาม — การสร้างโค้ด: การแปลงกราฟที่ปรับให้เหมาะสมเป็นคำสั่งเครื่องสำหรับสถาปัตยกรรม CPU เฉพาะ (ARM, ARM64, x86)

java
// การสาธิตการอินไลน์ — JIT จะอินไลน์เนื้อหาของเมธอด
public int inlineExample() {
    return square(5);
}

private int square(int x) {
    return x * x;
} // JIT จะแทนที่การเรียกด้วย return 5 * 5;

OSR — การแทนที่บนสแต็ก

เทคนิคพิเศษของ JIT — การแทนที่บนสแต็ก (OSR) หากเมธอดมีลูปยาวที่ไม่สิ้นสุดเป็นร้อยรอบ JIT สามารถคอมไพล์ลูป “ทันที” และแทนที่เวอร์ชันที่แปลความหมายด้วยเวอร์ชันที่คอมไพล์แล้วระหว่างการทำงาน OSR มีประสิทธิภาพโดยเฉพาะอย่างยิ่งสำหรับงานคำนวณ: การเรนเดอร์, การประมวลผลภาพ, การเข้ารหัส

JIT เทียบกับ AOT: การวิเคราะห์เปรียบเทียบ

JIT และ AOT เป็นสองแนวทางการคอมไพล์ที่มีการแลกเปลี่ยนที่ตรงกันข้าม JIT เสียสละความเร็วในการเริ่มต้นครั้งแรกเพื่อขนาดการแจกจ่ายที่กะทัดรัดและความสามารถในการปรับตัว AOT เสียสละเวลาการติดตั้งและพื้นที่ดิสก์เพื่อประสิทธิภาพสูงสุดตั้งแต่วินาทีแรก ไม่มีแนวทางใดที่ดีกว่าอย่างแท้จริง — การเลือกขึ้นอยู่กับสถานการณ์

ข้อได้เปรียบหลักของ JIT คือ การเพิ่มประสิทธิภาพแบบปรับตัว JIT สามารถใช้ข้อมูลโปรไฟล์ที่ไม่พร้อมใช้งานสำหรับ AOT: ชนิดวัตถุที่แน่นอน ความถี่ในการเรียกจริง รูปแบบการแตกแขนงจริง ซึ่งช่วยให้สามารถใช้การเพิ่มประสิทธิภาพเชิงรุกที่เป็นไปไม่ได้กับการคอมไพล์แบบคงที่ ตัวอย่างเช่น JIT สามารถ de-virtualize การเรียกเมธอดหากพบผู้รับเพียงชนิดเดียวในทางปฏิบัติ

เกณฑ์JITAOT
เวลาติดตั้งทันทีขึ้นอยู่กับขนาด
การเริ่มต้นครั้งแรกช้ากว่า (อุ่นเครื่อง)เร็ว
พื้นที่ดิสก์น้อยที่สุด+15–30%
ความสามารถในการปรับตัวสูงต่ำ
การใช้ CPUพุ่งสูงระหว่างการคอมไพล์เสถียร

เมื่อใดควรเลือก JIT

การคอมไพล์ JIT เหมาะสมกว่าเมื่อการปรับใช้ที่รวดเร็วและการประหยัดพื้นที่ดิสก์มีความสำคัญ ในบริบทของการพัฒนาโมบายล์ JIT เหมาะสำหรับแอปพลิเคชันที่อัปเดตบ่อยครั้ง (การทดสอบ A/B, การแก้ไขด่วน) JIT ยังสะดวกในระหว่างการพัฒนา เมื่อโค้ดถูกสร้างใหม่หลายสิบครั้งต่อวัน — ทุกวินาทีที่ประหยัดได้ในการคอมไพล์จะเร่งวงจรป้อนกลับ

ข้อดีของการคอมไพล์ JIT

JIT มอบข้อได้เปรียบเชิงปฏิบัติหลายประการแก่ผู้พัฒนา ข้อแรก — ขนาด APK เล็ก ด้วยแนวทาง JIT มีเพียงไบต์โค้ด (DEX) เท่านั้นที่ถูกบรรจุใน APK ซึ่งใช้พื้นที่น้อยกว่าโค้ดพื้นเมืองที่คอมไพล์แล้ว 20–30% สำหรับผู้ใช้ที่มีพื้นที่จัดเก็บภายในจำกัด นี่เป็นข้อได้เปรียบที่สำคัญ

ข้อได้เปรียบที่สองคือ การปรับตัวให้เข้ากับอุปกรณ์ JIT คอมไพล์โค้ดโดยคำนึงถึงสถาปัตยกรรม CPU จริง, ขนาด RAM และโหลดปัจจุบัน ตัวอย่างเช่น บนอุปกรณ์ที่มี RAM 2 GB, JIT อาจคอมไพล์อย่างไม่รุนแรงเพื่อประหยัดหน่วยความจำ ในขณะที่บนเรือธงที่มี 12 GB สามารถใช้การเพิ่มประสิทธิภาพทั้งหมดที่เป็นไปได้ การคอมไพล์ AOT ในทางกลับกัน จะกำหนดการตัดสินใจ ณ เวลาที่ติดตั้ง

ความเป็นอิสระจากแพลตฟอร์ม

ไบต์โค้ด ยังคงเป็นอิสระจากแพลตฟอร์ม ซึ่งทำให้การแจกจ่ายแอปพลิเคชันง่ายขึ้น APK หนึ่งทำงานบนอุปกรณ์ ARM, ARM64 และ x86 และ JIT สร้างโค้ดพื้นเมืองสำหรับแต่ละสถาปัตยกรรม แนวทาง AOT จะต้องรวมโค้ดพื้นเมืองหลายรูปแบบใน APK (เพิ่มขนาด) หรือคอมไพล์เวอร์ชันแยกต่างหากสำหรับแต่ละสถาปัตยกรรม

ข้อเสียและข้อจำกัดของ JIT

ข้อเสียหลักของ JIT คือ ความล่าช้าในการอุ่นเครื่อง ผู้ใช้พบกับความช้าในวินาทีแรกของแอปพลิเคชันขณะที่ JIT คอมไพล์เมธอดร้อน ในเกม สิ่งนี้ปรากฏเป็นการกระตุกในระดับเริ่มต้น ในแอปพลิเคชันที่มีแอนิเมชัน — การเปลี่ยนระหว่างหน้าจอครั้งแรกที่สะดุด

ข้อเสียที่สอง — การใช้พลังงาน กระบวนการคอมไพล์ทำให้ CPU ทำงานหนัก เพิ่มการใช้พลังงาน 10–20% ในช่วงอุ่นเครื่อง บนอุปกรณ์ที่ใช้แบตเตอรี่ สิ่งนี้ลดอายุการใช้งานแบตเตอรี่ โดยเฉพาะอย่างยิ่งในสถานการณ์ที่มีการรีสตาร์ทแอปพลิเคชันบ่อยครั้ง (การทำงานหลายอย่างพร้อมกันด้วยหน่วยความจำจำกัด ที่ระบบยกเลิกการโหลดและโหลดกระบวนการใหม่)

การกระจายตัวของแคช

อีกปัญหาหนึ่ง — การกระจายตัวของแคช JIT โค้ดที่คอมไพล์แล้วถูกเก็บในพื้นที่หน่วยความจำต่อเนื่อง เมื่อคลาสใหม่ถูกโหลดและเมธอดเพิ่มเติมถูกคอมไพล์ แคชจะกระจายตัว เพิ่มค่าใช้จ่ายในการจัดการหน่วยความจำ ใน Dalvik ปัญหานี้แก้ไขได้ด้วยการล้างแคชเป็นระยะ ใน ART แคช JIT ถูกจัดสรรแยกจากฮีปและใช้กลยุทธ์การจัดเรียงข้อมูลของตัวเอง

โหมดไฮบริด: สิ่งที่ดีที่สุดของทั้งสองโลก

แนวทางที่ทันสมัยใน ART — การคอมไพล์แบบไฮบริด ผสานจุดแข็งของ JIT และ AOT ระหว่างการติดตั้งแอปพลิเคชัน ไม่มีการคอมไพล์ใด ๆ — มีเพียงการตรวจสอบไบต์โค้ด (verify) ซึ่งรับประกันการติดตั้งที่รวดเร็วและการใช้พื้นที่น้อยที่สุด การเริ่มต้นครั้งแรกทำงานในโหมดแปลความหมายด้วยการคอมไพล์ JIT ของเมธอดร้อน — ผู้ใช้ได้รับประสิทธิภาพที่ยอมรับได้โดยไม่ต้องรอนาน

พร้อมกันนั้น โปรไฟล์เลอร์ในพื้นหลัง จะรวบรวมข้อมูลเกี่ยวกับการใช้งานจริง หลังจาก 2–3 การเริ่มต้นแอปพลิเคชันเต็มรูปแบบ โปรไฟล์จะมีความสมบูรณ์เพียงพอ และระบบจะเรียกใช้ dex2oat เพื่อคอมไพล์เมธอดร้อนเป็นโค้ดพื้นเมือง การดำเนินการนี้จะดำเนินการในพื้นหลังเมื่ออุปกรณ์ไม่ได้รับภาระ (กำลังชาร์จ, หน้าจอปิด) หลังจาก AOT ในพื้นหลังเสร็จสมบูรณ์ แอปพลิเคชันจะมีประสิทธิภาพเทียบเท่ากับการคอมไพล์ AOT เต็มรูปแบบ

bash
# บังคับเริ่มการคอมไพล์ในพื้นหลัง
adb shell cmd package compile -m speed-profile -f com.example.app

# ดูสถานะการคอมไพล์
adb shell cmd package dump-profiles com.example.app

ผลลัพธ์ของแนวทางไฮบริด

ตาม Google I/O 2017 การคอมไพล์แบบไฮบริดลดเวลาการติดตั้งแอปพลิเคชันลง 30–50% เมื่อเทียบกับ AOT บริสุทธิ์ พื้นที่ดิสก์ที่ถูกครอบครองบนพาร์ติชันระบบลดลง 20–30% ในขณะเดียวกัน ประสิทธิภาพหลังการคอมไพล์ในพื้นหลังเทียบเท่ากับระดับของ AOT เต็ม สถานการณ์เดียวที่ไฮบริดด้อยกว่า AOT คือการเริ่มต้นครั้งแรกทันทีหลังการติดตั้ง: แอปพลิเคชันทำงานในโหมด JIT และอาจช้ากว่า 10–15%

คำถามที่พบบ่อย

การคอมไพล์ JIT ในคำง่าย ๆ คืออะไร?

JIT เป็นวิธีเพิ่มความเร็วโปรแกรมที่โค้ดถูกแปลเป็นภาษาเครื่องไม่ใช่ล่วงหน้า แต่เป็นส่วน ๆ ระหว่างการทำงาน ส่วนที่บ่อยที่สุดถูกคอมไพล์และเก็บในแคช ในขณะที่ส่วนที่หายากยังคงอยู่ในรูปแบบเดิม

JIT แตกต่างจาก AOT อย่างไร?

JIT คอมไพล์โค้ดระหว่างการทำงาน ประหยัดพื้นที่และเร่งการติดตั้ง AOT คอมไพล์โค้ดทั้งหมดล่วงหน้า — แอปพลิเคชันเริ่มต้นเร็วขึ้นแต่ต้องการพื้นที่ดิสก์และเวลาติดตั้งมากกว่า

ทำไม JIT ถึงถูกลบออกจาก Android?

JIT ไม่ได้ถูกลบ — มัน วิวัฒนาการ ใน Android 5.0, Dalvik ที่มี JIT ถูกแทนที่ด้วย ART ที่มี AOT บริสุทธิ์ ใน Android 7.0, JIT กลับมาสู่ ART ในฐานะส่วนหนึ่งของระบบไฮบริดที่ทำงานร่วมกับการคอมไพล์ AOT ในพื้นหลังเพื่อประสิทธิภาพที่เหมาะสมที่สุด

JIT ส่งผลต่อการใช้พลังงานอย่างไร?

JIT เพิ่มการใช้พลังงาน 10–20% ในช่วงอุ่นเครื่องเนื่องจากโหลดของ CPU หลังจากคอมไพล์เมธอดร้อนเสร็จ การใช้พลังงานจะกลับสู่ระดับปกติ โหมดไฮบริดของ ART ลดการพุ่งสูงเหล่านี้ผ่านการคอมไพล์ในพื้นหลัง

การอุ่นเครื่องของ JIT ผู้ใช้มองเห็นได้หรือไม่?

ใช่ ในสถานการณ์ที่มีการคำนวณเข้มข้น ผู้ใช้อาจสังเกตเห็น ความช้า ในวินาทีแรกของการทำงานของแอปพลิเคชันหรือตอนเริ่มเกม ใน Android เวอร์ชันสมัยใหม่ (8.0+) โหมดไฮบริดลดผลกระทบนี้ด้วยการคอมไพล์แบบมีโปรไฟล์

สรุป

  • JIT (Just-In-Time) คือการคอมไพล์แบบไดนามิกที่แปลงไบต์โค้ดเป็นคำสั่งเครื่องระหว่างการทำงาน
  • ใน Android, JIT วิวัฒนาการ: แบบร่องรอยใน Dalvik → AOT เต็ม → ไฮบริด JIT+AOT ใน ART สมัยใหม่
  • เมธอดร้อน ถูกตรวจจับผ่านตัวนับการเรียกและคอมไพล์เมื่อเกินเกณฑ์ (~200 การเรียก)
  • OSR (การแทนที่บนสแต็ก) ช่วยให้คอมไพล์ลูปยาว ทันที โดยไม่ขัดจังหวะการทำงาน
  • ข้อดีหลักของ JIT: ขนาด APK เล็ก, ติดตั้งเร็ว และ การปรับตัวให้เข้ากับอุปกรณ์
  • ข้อเสียหลัก: ความล่าช้าในการอุ่นเครื่อง, การใช้พลังงานสูงสุด และ การกระจายตัวของแคช
  • โหมดไฮบริดของ ART (Android 7.0+) ลดเวลาติดตั้ง 30–50% พร้อมรักษาประสิทธิภาพสูง

เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร

IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ

ปรึกษาโครงการ

อ่านเพิ่มเติม