การนำคอมไพเลอร์ ART just-In-time (JIT) ไปใช้

รันไทม์ของ Android (ART) มีคอมไพเลอร์แบบ Just-in-Time (JIT) พร้อมการทำโปรไฟล์โค้ดที่ช่วยปรับปรุงประสิทธิภาพของแอปพลิเคชัน Android อย่างต่อเนื่องขณะทำงาน คอมไพเลอร์ JIT ช่วยเสริมคอมไพเลอร์ล่วงหน้า (AOT) ในปัจจุบันของ ART และปรับปรุงประสิทธิภาพรันไทม์ ประหยัดพื้นที่จัดเก็บ และเร่งความเร็วในการอัปเดตแอปพลิเคชันและระบบ นอกจากนี้ยังปรับปรุงคอมไพเลอร์ AOT โดยหลีกเลี่ยงไม่ให้ระบบทำงานช้าลงระหว่างการอัปเดตแอปพลิเคชันอัตโนมัติหรือคอมไพล์แอปพลิเคชันใหม่ระหว่างการอัปเดตแบบ over-the-air (OTA)

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

สถาปัตยกรรม 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. daemon การคอมไพล์ AOT ( dex2oat ) แยกวิเคราะห์ไฟล์นั้นเพื่อขับเคลื่อนการคอมไพล์

    JIT ภูต
    รูปที่ 3 กิจกรรม JIT daemon

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

เวิร์กโฟลว์ JIT

สถาปัตยกรรม JIT
รูปที่ 4 การไหลของข้อมูล JIT
  • ข้อมูลโปรไฟล์ถูกเก็บไว้ในแคชรหัสและอยู่ภายใต้การรวบรวมขยะภายใต้แรงกดดันของหน่วยความจำ
    • ไม่มีการรับประกันว่าสแน็ปช็อตที่ถ่ายเมื่อแอปพลิเคชันอยู่ในพื้นหลังจะมีข้อมูลที่สมบูรณ์ (เช่น ทุกอย่างที่เป็น JITed)
    • ไม่มีการพยายามทำให้แน่ใจว่าทุกอย่างถูกบันทึก (เนื่องจากสิ่งนี้อาจส่งผลต่อประสิทธิภาพรันไทม์)
  • วิธีการสามารถอยู่ในสถานะที่แตกต่างกันสามสถานะ:
    • ตีความ (รหัส dex)
    • JIT เรียบเรียง
    • ทอท. เรียบเรียง
    หากมีทั้งรหัส JIT และ AOT (เช่น เนื่องจากการยกเลิกการเพิ่มประสิทธิภาพซ้ำหลายครั้ง) ขอแนะนำให้ใช้รหัส JITed
  • ความต้องการหน่วยความจำเพื่อเรียกใช้ 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
    

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

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

  • สำหรับหนึ่งแพ็คเกจ:
    adb shell cmd package compile --reset my-package
    
  • สำหรับแพ็คเกจทั้งหมด:
    adb shell cmd package compile --reset -a