הטמעת מהדר של ART בדיוק בזמן

סביבת זמן הריצה ל-Android‏ (ART) כוללת קומפיילר JIT עם פרופיל קוד, שמשפר באופן מתמשך את הביצועים של אפליקציות ל-Android בזמן שהן פועלות. הקומפיילר JIT משלים את הקומפיילר הנוכחי של ART מראש (AOT) ומשפר את ביצועי זמן הריצה, חוסך מקום אחסון ומזרז את העדכונים של האפליקציות והמערכת. הוא גם משפר את מהדר ה-AOT בכך שהוא מונע האטה של המערכת במהלך עדכונים אוטומטיים של אפליקציות או קומפילציה מחדש של אפליקציות במהלך עדכונים דרך האוויר (OTA).

למרות ש-JIT ו-AOT משתמשים באותו קומפיילר עם קבוצה דומה של אופטימיזציות, יכול להיות שהקוד שנוצר לא יהיה זהה. הידור JIT משתמש במידע על סוג זמן הריצה, יכול לבצע הטמעה טובה יותר של קוד (inlining) ומאפשר הידור של החלפה במחסנית (OSR), וכל אלה יוצרים קוד שונה במקצת.

ארכיטקטורת JIT

ארכיטקטורת JIT
איור 1. ארכיטקטורת JIT.

הידור JIT

הידור JIT כולל את הפעילויות הבאות:

הידור בהנחיית פרופיל
איור 2. הידור מונחה-פרופיל.
  1. המשתמש מפעיל את האפליקציה, ואז ART מפעיל את טעינת הקובץ .dex.
    • אם קובץ .oat (הקובץ הבינארי של AOT עבור קובץ .dex ) זמין, ART משתמש בו ישירות. למרות שקובצי .oat נוצרים באופן קבוע, הם לא תמיד מכילים קוד שעבר קומפילציה (קובץ בינארי AOT).
    • אם הקובץ .oat לא מכיל קוד שעבר קומפילציה, ART מריץ את הקובץ .dex באמצעות JIT והמתורגמן.
  2. הידור JIT מופעל לכל אפליקציה שלא עברה הידור לפי מסנן ההידור speed (שמציין "הידור של כמה שיותר מהאפליקציה").
  3. נתוני הפרופיל של JIT נשמרים בקובץ בספריית מערכת שרק האפליקציה יכולה לגשת אליה.
  4. הדמון של קומפילציית AOT‏ (dex2oat) מנתח את הקובץ הזה כדי להפעיל את הקומפילציה.

    דימון JIT
    איור 3. פעילויות של שד JIT.

שירות Google Play הוא דוגמה לשירות שמשמש אפליקציות אחרות שמתנהגות באופן דומה לספריות משותפות.

תהליך עבודה של JIT

ארכיטקטורת JIT
איור 4. זרימת נתונים JIT.
  • מידע על פרופילים מאוחסן במטמון הקוד ועובר איסוף אשפה כשיש עומס על הזיכרון.
    • אין ערובה לכך שתמונת מצב שצולמה כשהאפליקציה הייתה ברקע תכיל נתונים מלאים (כלומר, כל מה שעבר קומפילציה מסוג JIT).
    • אין ניסיון לוודא שהכול מתועד (כי זה עלול להשפיע על הביצועים בזמן הריצה).
  • השיטות יכולות להיות בשלושה מצבים שונים:
    • מפורש (קוד dex)
    • הידור JIT
    • הידור AOT
    אם קיימים גם קוד JIT וגם קוד AOT (למשל בגלל ביטול אופטימיזציה חוזר), קוד ה-JIT מקבל עדיפות.
  • דרישת הזיכרון להפעלת JIT בלי להשפיע על הביצועים של אפליקציה שפועלת בחזית תלויה באפליקציה הרלוונטית. אפליקציות גדולות דורשות יותר זיכרון מאפליקציות קטנות. באופן כללי, אפליקציות גדולות מתייצבות סביב 4MB.

הפעלת רישום ביומן של 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 

הערה: בניגוד לפקודה ל-Android 13 או לגרסאות קודמות, הפקודה הזו לא מוחקת נתונים של פרופיל חיצוני (‎.dm) שמותקן עם האפליקציה.

כדי למחוק נתונים מקומיים של פרופיל ולהסיר קוד מהודר שנוצר מנתונים מקומיים של פרופיל (כלומר, כדי לאפס למצב ההתקנה), מריצים את הפקודה הבאה:

adb shell pm compile --reset 

הערה: הפקודה הזו לא מסירה קוד שעבר קומפילציה ונוצר מנתוני פרופיל חיצוניים (‎.dm) שמותקנים עם האפליקציה.

כדי לנקות את כל הקוד שעבר קומפילציה, מריצים את הפקודה הבאה:

adb shell cmd package compile -m verify -f 

הערה: הפקודה הזו שומרת את נתוני הפרופיל המקומיים.