ใช้คอมไพเลอร์แบบ Just-in-Time ของ ART

รันไทม์ของ Android (ART) มีคอมไพเลอร์แบบคอมไพล์ JIT (Just-In-Time) พร้อมการสร้างโปรไฟล์โค้ดที่ปรับปรุงประสิทธิภาพของแอปพลิเคชัน Android อย่างต่อเนื่องขณะทำงาน คอมไพเลอร์แบบคอมไพล์ JIT จะเสริมการทำงานของคอมไพเลอร์แบบคอมไพล์ AOT (Ahead-Of-Time) ปัจจุบันของ ART และปรับปรุงประสิทธิภาพรันไทม์ ประหยัดพื้นที่เก็บข้อมูล รวมถึงเร่งการอัปเดตแอปพลิเคชันและระบบ นอกจากนี้ยังปรับปรุงคอมไพเลอร์แบบคอมไพล์ AOT โดยหลีกเลี่ยงการทำงานช้าของระบบระหว่างการอัปเดตแอปพลิเคชันอัตโนมัติหรือการคอมไพล์แอปพลิเคชันอีกครั้งระหว่างการอัปเดตผ่านอากาศ (OTA)

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

สถาปัตยกรรมคอมไพเลอร์แบบคอมไพล์ JIT

สถาปัตยกรรม JIT
รูปที่ 1 สถาปัตยกรรมคอมไพเลอร์แบบคอมไพล์ JIT

การคอมไพล์ JIT

การคอมไพล์ JIT เกี่ยวข้องกับกิจกรรมต่อไปนี้

การเรียบเรียงเพลงที่แนะนำโดยโปรไฟล์
รูปที่ 2 การคอมไพล์ที่อิงตามโปรไฟล์
  1. ผู้ใช้เรียกใช้แอป ซึ่งจะทริกเกอร์ให้ ART โหลดไฟล์ .dex
    • หากมีไฟล์ .oat (ไบนารี AOT สำหรับไฟล์ .dex ) ART จะใช้ไฟล์ดังกล่าวโดยตรง แม้ว่าไฟล์ .oat จะถูกสร้างขึ้นเป็นประจำ แต่ไฟล์ดังกล่าวก็ไม่ได้มีโค้ดที่คอมไพล์แล้ว (ไบนารี AOT) เสมอไป
    • หากไฟล์ .oat ไม่มีโค้ดที่คอมไพล์แล้ว ART จะเรียกใช้ คอมไพเลอร์แบบคอมไพล์ JIT และอินเทอร์พรีเตอร์เพื่อเรียกใช้ไฟล์ .dex
  2. ระบบจะเปิดใช้คอมไพเลอร์แบบคอมไพล์ JIT สำหรับแอปพลิเคชันที่ไม่ได้คอมไพล์ตามตัวกรองการคอมไพล์ speed (ซึ่งระบุว่า "คอมไพล์จากแอปให้ได้มากที่สุด")
  3. ระบบจะดัมพ์ข้อมูลโปรไฟล์คอมไพเลอร์แบบคอมไพล์ JIT ลงในไฟล์ในไดเรกทอรีระบบที่แอปพลิเคชันเท่านั้นที่เข้าถึงได้
  4. ดีมอนการคอมไพล์ AOT (dex2oat) จะแยกวิเคราะห์ไฟล์ดังกล่าวเพื่อขับเคลื่อนการคอมไพล์

    Daemon ของ JIT
    รูปที่ 3 กิจกรรมของ Daemon JIT

บริการ Google Play เป็นตัวอย่างที่แอปพลิเคชันอื่นๆ ใช้ซึ่งทำงานคล้ายกับไลบรารีที่แชร์

เวิร์กโฟลว์คอมไพเลอร์แบบคอมไพล์ JIT

สถาปัตยกรรม JIT
รูปที่ 4 โฟลว์ข้อมูลคอมไพเลอร์แบบคอมไพล์ JIT
  • ระบบจะจัดเก็บข้อมูลการสร้างโปรไฟล์ไว้ในแคชโค้ดและทำการเก็บขยะเมื่อหน่วยความจำเหลือน้อย
    • ไม่มีการรับประกันว่าสแนปชอตที่ถ่ายเมื่อแอปพลิเคชันทำงานอยู่เบื้องหลังจะมีข้อมูลครบถ้วน (เช่น ทุกสิ่งที่คอมไพเลอร์แบบคอมไพล์ JIT คอมไพล์)
    • ไม่มีการพยายามบันทึกทุกอย่าง (เนื่องจากอาจส่งผลต่อประสิทธิภาพรันไทม์)
  • เมธอดอาจอยู่ใน 3 สถานะที่แตกต่างกัน ได้แก่
    • ตีความ (โค้ด dex)
    • คอมไพล์ JIT
    • คอมไพล์ AOT
    หากมีทั้งโค้ดคอมไพเลอร์แบบคอมไพล์ JIT และคอมไพเลอร์แบบคอมไพล์ AOT (เช่น เนื่องจากการยกเลิกการเพิ่มประสิทธิภาพซ้ำๆ) ระบบจะเลือกใช้โค้ดที่คอมไพเลอร์แบบคอมไพล์ JIT คอมไพล์
  • ข้อกำหนดด้านหน่วยความจำในการเรียกใช้คอมไพเลอร์แบบคอมไพล์ JIT โดยไม่ส่งผลต่อประสิทธิภาพของแอปที่ทำงานอยู่เบื้องหน้าจะขึ้นอยู่กับแอปที่เป็นปัญหา แอปขนาดใหญ่ต้องใช้หน่วยความจำมากกว่าแอปขนาดเล็ก โดยทั่วไปแล้ว แอปขนาดใหญ่จะคงที่อยู่ที่ประมาณ 4 MB

เปิดการบันทึกคอมไพเลอร์แบบคอมไพล์ JIT

หากต้องการเปิดการบันทึกคอมไพเลอร์แบบคอมไพล์ JIT ให้เรียกใช้คำสั่งต่อไปนี้

adb root
adb shell stop
adb shell setprop dalvik.vm.extra-opts -verbose:jit
adb shell start

ปิดใช้คอมไพเลอร์แบบคอมไพล์ JIT

หากต้องการปิดใช้คอมไพเลอร์แบบคอมไพล์ JIT ให้เรียกใช้คำสั่งต่อไปนี้

adb root
adb shell stop
adb shell setprop dalvik.vm.usejit false
adb shell start

บังคับคอมไพล์

หากต้องการบังคับคอมไพล์ ให้เรียกใช้คำสั่งต่อไปนี้

adb shell cmd package compile

กรณีการใช้งานทั่วไปสำหรับการบังคับคอมไพล์แพ็กเกจที่เฉพาะเจาะจงมีดังนี้

  • อิงตามโปรไฟล์
    adb shell cmd package compile -m speed-profile -f my-package
    
  • โดยสมบูรณ์
    adb shell cmd package compile -m speed -f my-package
    

กรณีการใช้งานทั่วไปสำหรับการบังคับคอมไพล์แพ็กเกจทั้งหมดมีดังนี้

  • อิงตามโปรไฟล์
    adb shell cmd package compile -m speed-profile -f -a
    
  • โดยสมบูรณ์
    adb shell cmd package compile -m speed -f -a
    

ล้างข้อมูลโปรไฟล์

ใน Android 13 หรือเวอร์ชันก่อนหน้า

หากต้องการล้างข้อมูลโปรไฟล์ในเครื่องและนำโค้ดที่คอมไพล์แล้วออก ให้เรียกใช้คำสั่งต่อไปนี้

adb shell pm compile --reset 

ใน Android 14 หรือเวอร์ชันที่ใหม่กว่า

หากต้องการล้างข้อมูลโปรไฟล์ในเครื่องเท่านั้น ให้เรียกใช้คำสั่งต่อไปนี้

adb shell pm art clear-app-profiles 

หมายเหตุ: คำสั่งนี้จะไม่ล้างข้อมูลโปรไฟล์ภายนอก (`.dm`) ที่ติดตั้งพร้อมกับแอป ซึ่งแตกต่างจากคำสั่งสำหรับ Android 13 หรือเวอร์ชันก่อนหน้า

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

adb shell pm compile --reset 

หมายเหตุ: คำสั่งนี้จะไม่นำโค้ดที่คอมไพล์แล้วซึ่งสร้างจาก ข้อมูลโปรไฟล์ภายนอก (`.dm`) ที่ติดตั้งพร้อมกับแอปออก

หากต้องการล้างโค้ดที่คอมไพล์แล้วทั้งหมด ให้เรียกใช้คำสั่งต่อไปนี้

adb shell cmd package compile -m verify -f 

หมายเหตุ: คำสั่งนี้จะเก็บข้อมูลโปรไฟล์ในเครื่องไว้