סביבת זמן הריצה ל-Android (ART) כוללת קומפיילר JIT עם פרופיל קוד, שמשפר באופן מתמשך את הביצועים של אפליקציות ל-Android בזמן שהן פועלות. הקומפיילר JIT משלים את הקומפיילר הנוכחי של ART מראש (AOT) ומשפר את ביצועי זמן הריצה, חוסך מקום אחסון ומזרז את העדכונים של האפליקציות והמערכת. הוא גם משפר את מהדר ה-AOT בכך שהוא מונע האטה של המערכת במהלך עדכונים אוטומטיים של אפליקציות או קומפילציה מחדש של אפליקציות במהלך עדכונים דרך האוויר (OTA).
למרות ש-JIT ו-AOT משתמשים באותו קומפיילר עם קבוצה דומה של אופטימיזציות, יכול להיות שהקוד שנוצר לא יהיה זהה. הידור JIT משתמש במידע על סוג זמן הריצה, יכול לבצע הטמעה טובה יותר של קוד (inlining) ומאפשר הידור של החלפה במחסנית (OSR), וכל אלה יוצרים קוד שונה במקצת.
ארכיטקטורת JIT
הידור JIT
הידור JIT כולל את הפעילויות הבאות:
- המשתמש מפעיל את האפליקציה, ואז ART מפעיל את טעינת הקובץ
.dex.- אם קובץ
.oat(הקובץ הבינארי של AOT עבור קובץ.dex) זמין, ART משתמש בו ישירות. למרות שקובצי.oatנוצרים באופן קבוע, הם לא תמיד מכילים קוד שעבר קומפילציה (קובץ בינארי AOT). - אם הקובץ
.oatלא מכיל קוד שעבר קומפילציה, ART מריץ את הקובץ.dexבאמצעות JIT והמתורגמן.
- אם קובץ
- הידור JIT מופעל לכל אפליקציה שלא עברה הידור לפי מסנן ההידור
speed(שמציין "הידור של כמה שיותר מהאפליקציה"). - נתוני הפרופיל של JIT נשמרים בקובץ בספריית מערכת שרק האפליקציה יכולה לגשת אליה.
- הדמון של קומפילציית AOT (
dex2oat) מנתח את הקובץ הזה כדי להפעיל את הקומפילציה.
איור 3. פעילויות של שד JIT.
שירות Google Play הוא דוגמה לשירות שמשמש אפליקציות אחרות שמתנהגות באופן דומה לספריות משותפות.
תהליך עבודה של JIT
- מידע על פרופילים מאוחסן במטמון הקוד ועובר איסוף אשפה כשיש עומס על הזיכרון.
- אין ערובה לכך שתמונת מצב שצולמה כשהאפליקציה הייתה ברקע תכיל נתונים מלאים (כלומר, כל מה שעבר קומפילציה מסוג JIT).
- אין ניסיון לוודא שהכול מתועד (כי זה עלול להשפיע על הביצועים בזמן הריצה).
- השיטות יכולות להיות בשלושה מצבים שונים:
- מפורש (קוד dex)
- הידור JIT
- הידור AOT
- דרישת הזיכרון להפעלת JIT בלי להשפיע על הביצועים של אפליקציה שפועלת בחזית תלויה באפליקציה הרלוונטית. אפליקציות גדולות דורשות יותר זיכרון מאפליקציות קטנות. באופן כללי, אפליקציות גדולות מתייצבות סביב 4MB.
הפעלת רישום ביומן של JIT
כדי להפעיל את הרישום ביומן JIT, מריצים את הפקודות הבאות:
adb rootadb shell stopadb shell setprop dalvik.vm.extra-opts -verbose:jitadb shell start
השבתת JIT
כדי להשבית את JIT, מריצים את הפקודות הבאות:
adb rootadb shell stopadb shell setprop dalvik.vm.usejit falseadb 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
הערה: הפקודה הזו שומרת את נתוני הפרופיל המקומיים.