پیاده سازی ART just-in-time کامپایلر

زمان اجرای اندروید (ART) شامل یک کامپایلر just-in-time (JIT) با قابلیت پروفایلینگ کد است که به طور مداوم عملکرد برنامه‌های اندروید را در حین اجرا بهبود می‌بخشد. کامپایلر JIT، کامپایلر فعلی ahead-of-time (AOT) ART را تکمیل می‌کند و عملکرد زمان اجرا را بهبود می‌بخشد، در فضای ذخیره‌سازی صرفه‌جویی می‌کند و سرعت به‌روزرسانی‌های برنامه و سیستم را افزایش می‌دهد. همچنین با جلوگیری از کند شدن سیستم در حین به‌روزرسانی‌های خودکار برنامه یا کامپایل مجدد برنامه‌ها در حین به‌روزرسانی‌های over-the-air (OTA)، کامپایلر AOT را بهبود می‌بخشد.

اگرچه JIT و AOT از کامپایلر یکسانی با مجموعه‌ای مشابه از بهینه‌سازی‌ها استفاده می‌کنند، اما کد تولید شده ممکن است یکسان نباشد. JIT از اطلاعات نوع زمان اجرا استفاده می‌کند، می‌تواند inlineing بهتری انجام دهد و کامپایل جایگزینی پشته (OSR) را امکان‌پذیر می‌کند، که همه این‌ها کد کمی متفاوت تولید می‌کنند.

معماری JIT

معماری JIT
شکل ۱. معماری JIT.

کامپایل JIT

کامپایل JIT شامل فعالیت‌های زیر است:

کامپوننت هدایت‌شده توسط پروفایل
شکل ۲. کامپایل هدایت‌شده توسط پروفایل.
  1. کاربر برنامه را اجرا می‌کند، که سپس ART را برای بارگذاری فایل .dex فعال می‌کند.
    • اگر فایل .oat (فایل دودویی AOT برای فایل .dex ) موجود باشد، ART مستقیماً از آن استفاده می‌کند. اگرچه فایل‌های .oat مرتباً تولید می‌شوند، اما همیشه حاوی کد کامپایل شده (فایل دودویی AOT) نیستند.
    • اگر فایل .oat حاوی کد کامپایل شده نباشد، ART از طریق JIT و مفسر، فایل .dex را اجرا می‌کند.
  2. JIT برای هر برنامه‌ای که طبق فیلتر speed کامپایل (که می‌گوید «تا جایی که می‌توانید از برنامه کامپایل کنید») کامپایل نشده باشد، فعال است.
  3. داده‌های پروفایل JIT در فایلی در دایرکتوری سیستم ذخیره می‌شوند که فقط برنامه می‌تواند به آن دسترسی داشته باشد.
  4. دیمن کامپایل AOT ( dex2oat ) آن فایل را برای اجرای کامپایل خود تجزیه می‌کند.

    دیمن JIT
    شکل 3. فعالیت‌های دیمن JIT.

سرویس گوگل پلی نمونه‌ای است که توسط سایر برنامه‌هایی که رفتاری مشابه کتابخانه‌های اشتراکی دارند، استفاده می‌شود.

گردش کار JIT

معماری JIT
شکل ۴. جریان داده JIT.
  • اطلاعات پروفایلینگ در حافظه پنهان کد ذخیره می‌شود و تحت فشار حافظه، در معرض جمع‌آوری زباله قرار می‌گیرد.
    • هیچ تضمینی وجود ندارد که اسنپ‌شاتی که هنگام اجرای برنامه در پس‌زمینه گرفته می‌شود، حاوی داده‌های کامل (یعنی هر آنچه که JIT شده است) باشد.
    • هیچ تلاشی برای اطمینان از ثبت همه چیز وجود ندارد (زیرا این می‌تواند بر عملکرد زمان اجرا تأثیر بگذارد).
  • متدها می‌توانند در سه حالت مختلف باشند:
    • تفسیر شده (کد dex)
    • کامپایل شده با JIT
    • کامپایل شده توسط AOT
    اگر هر دو کد JIT و AOT وجود داشته باشند (مثلاً به دلیل عدم بهینه‌سازی مکرر)، کد JITed ترجیح داده می‌شود.
  • میزان حافظه مورد نیاز برای اجرای JIT بدون تأثیر بر عملکرد برنامه در پیش‌زمینه، به برنامه مورد نظر بستگی دارد. برنامه‌های بزرگ به حافظه بیشتری نسبت به برنامه‌های کوچک نیاز دارند. به طور کلی، برنامه‌های بزرگ حدود ۴ مگابایت حافظه نیاز دارند.

فعال کردن گزارش‌گیری 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 pm compile --reset 

در اندروید ۱۴ یا بالاتر

برای پاک کردن فقط داده‌های پروفایل محلی:

adb shell pm art clear-app-profiles 

توجه: برخلاف دستور مربوط به اندروید ۱۳ یا قبل از آن، این دستور داده‌های پروفایل خارجی (`.dm`) که با برنامه نصب شده‌اند را پاک نمی‌کند.

برای پاک کردن داده‌های پروفایل محلی و حذف کد کامپایل شده تولید شده از داده‌های پروفایل محلی (یعنی برای تنظیم مجدد به حالت نصب)، دستور زیر را اجرا کنید:

adb shell pm compile --reset 

توجه: این دستور، کد کامپایل‌شده‌ی تولیدشده از داده‌های پروفایل خارجی (`.dm`) که با برنامه نصب شده است را حذف نمی‌کند.

برای پاک کردن تمام کدهای کامپایل شده، این دستور را اجرا کنید:

adb shell cmd package compile -m verify -f 

نکته: این دستور داده‌های پروفایل محلی را حفظ می‌کند.