JIT (Just-In-Time) — proqramın aralıq təmsilini və ya bayt kodunu bilavasitə icra zamanı maşin təlimatlarına çevirən dinamik kompilasiya texnologiyasıdır. Android-də JIT kompilatoru ilk dəfə 2.2 Froyo versiyasında Dalvik virtual maşının tərkibində peyda olmuş və proqramların icrasını 2–5 dəfə sürətləndirmişdir. Google, 2024 məlumatlarına görə, ART-də müasir JIT interpretasiyanı profil edilmiş hot-metod kompilasiyası ilə birləşdirir.
Əsas məqamlar
Just-In-Time (JIT) — mənbə və ya bayt kodunun əvvəlcədən (AOT-da olduğu kimi) deyil, proqramın müvafiq hissəsinin ilk çağırışı anında maşın təlimatlarına çevrildiyi kompilasiya üsuludur. “Just-In-Time” termini kompilasiyanın “tam vaxtında” — icradan bilavasitə əvvəl baş verdiyini bildirir.
JIT konsepsiyası 1960-cı illərdən mövcuddur, lakin geniş yayılması 1995-ci ildə Java Virtual Machine-in meydana çıxması ilə baş vermişdir. JIT bayt kodunun daşına bilmə xüsusiyyətini (bir dəfə yazırıq — hər yerdə işlədirik) native koda yaxın performansla birləşdirməyə imkan verir. Java HotSpot VM-də JIT kompilatoru icra olunan kodu təhlil edir və vaxt və yaddaşa qənaət edərək yalnız ən kritik hissələri kompilasiya edir.
JIT kompilatoru girişdə bayt kodunu alır, onu interpretasiya edir və paralel olaraq statistika toplayır. Kodun müəyyən hissəsi (metod, dövr) kifayət qədər tez-tez çağrıldıqda, JIT kompilasiya qərarı verir. Kompilasiya edilmiş maşın kodu keş yaddaşında saxlanılır — təkrari çağırışlarda hazır versiyadan istifadə olunur. Bu, bütün proqramı kompilasiya etmək zörurəti olmadan sürətlənməni təmin edir.
// Nümunə: metod çoxsaylı çağırışdan sonra hot olacaq
public class HotMethod {
private int compute(int n) {
int sum = 0;
for (int i = 0; i < n; i++) {
sum += i * i;
}
return sum;
}
}
// Dövrdə 500 dəfə çağırma — JIT compute kompilasiya edəcək
for (int t = 0; t < 500; t++) {
hot.compute(1000);
}
Android-də JIT kompilasiyası üç təkamül mərhələsi keçmişdir. Birinci mərhələ — JIT-siz Dalvik (Android 1.0–2.1): DEX bayt kodunun təmiz interpretasiyası. İkinci mərhələ — JIT-li Dalvik (Android 2.2–4.4): proqramları 2–5 dəfə sürətləndirən JIT kompilatorunun meydana çıxması. Üçüncü mərhələ — hibrid JIT-li ART (Android 7.0+): JIT-in yeni keyfiyyətdə qayıdışı.
Dalvik-də JIT trace-based kompilator kimi tətbiq edilmişdir. O, ayrı-ayrı metodları deyil, ardıcıl olaraq tez-tez icra olunan təlimat zəncirlərini (traces) təhlil edirdi. Bu, bir neçe metodu əhatə edən bütöv icra yollarını kompilasiya etməyə imkan verirdi. Belə yanaşma kiçik təlimat keş yaddaşı olan mobil prosessorlar üçün səmərəli idi, çünki kompilasiya edilmiş trace L1 keşində yerləşirdi.
Android 7.0 Nougat-dan başlayaraq, ART icra profilləri əsasında ayrı-ayrı metodları kompilasiya edən method-based JIT istifadə edir. Bu JIT Dalvik JIT-dən əhəmiyyətli dərəcədə sürətli işləyir: bir metodun tipik kompilasiya müddəti Dalvik-də 3–5 ms-ə qarşı 0.5–1 ms təşkil edir. Kompilasiya edilmiş kod proqramın yığınında deyil, ayrıca yaddaş sahəsində (JIT code cache) saxlanılır ki, bu da fraqmentasiyanı azaldır.
| Parametr | Dalvik JIT | ART JIT |
|---|---|---|
| Növ | Trace-based | Method-based |
| Kompilasiya sürəti | 3–5 ms/metod | 0.5–1 ms/metod |
| Kompilasiya həddi | ~200 çağırış | Dinamik |
| Kod keşi | Proqram yığınında | JIT code cache |
| Profilləşdirmə | Daxili | Xarici .prof faylları |
JIT-in mərkəzi mexanizmi — hot-metodların aşkarlanması. Hər metod çağırışı daxili sayacı artırır. Sayaq həddi keçdikdə, metod “isti” kimi qeyd olunur və kompilasiyaya göndərilir. Dalvik-də hədd sərt şəkildə təyin edilmişdi (~200 çağırış). ART-də sayaqlar cihazın mövcud resurslarından asılı olaraq dinamik şəkildə tənzimlənir.
Kompilasiya prosesi bir neçe mərhələni əhatə edir. Birinci — bayt kodunun təhlili: JIT təlimat axını öyrənir və məlumat axını qrafiki (data-flow graph) qurur. İkinci — optimallaşdırma: kiçik metodların inline edilməsi, ölü kodun silinməsi, sabitlərin yığilması. Üçüncü — kod yaradılması: optimallaşdırılmış qrafikin müəyyən CPU arxitekturası (ARM, ARM64, x86) üçün maşın təlimatlarına çevrilməsi.
// Inlining nümayişi — JIT metodun bodisini əvəz edəcək
public int inlineExample() {
return square(5);
}
private int square(int x) {
return x * x;
} // JIT çağırışı return 5 * 5; ilə əvəz edəcək
JIT-in xüsusi texnikası — On-Stack Replacement (OSR). Metod yüzlərlə iterasiya çəkən uzun bir dövr ehtiva edərsə, JIT dövrü “uçarkən” kompilasiya edə və interpretasiya olunmuş versiyanı bilavasitə icra zamanı kompilasiya edilmiş versiya ilə əvəz edə bilər. OSR xüsusilə hesablama tapşırıqları üçün səmərəlidir: renderinq, şəkil emalı, kriptoqrafiya.
JIT və AOT — əks kompromislərə malik iki yanaşmadır. JIT paylamaşın yığcamlığı və uyğunlaşma qabiliyyəti naminə ilk işə salınma sürətindən qurban verir. AOT maksimal performansı ilk saniyədən təmin etmək naminə quraşdırma vaxtı və disk yerindən qurban verir. Heç bir yanaşma mütləq şəkildə daha yaxşı deyil — seçim ssenaridən asılıdır.
JIT-in əsas üstünlüyü adaptiv optimallaşdırmadır. JIT AOT üçün əlçatmaz olan profil məlumatlarından istifadə edə bilər: obyektlərin dəqiq növləri, real çağırış tezliyi, faktiki budaqlanmalar. Bu, statik kompilasiyada mümkün olmayan aqressiv optimallaşdırmaları tətbiq etməyə imkan verir. Məsələn, JIT praktikada yalnız bir qəbuledici növü varsa, metod çağırışlarını virtualizasiya edə bilər (devirtualize).
| Meyar | JIT | AOT |
|---|---|---|
| Quraşdırma müddəti | Anında | Ölçüdən asılı |
| İlk işə salınma | Yavaş (isinqəlmə) | Sürətli |
| Disk həcmi | Minimal | +15–30% |
| Uyğunlaşma | Yüksək | Aşağı |
| CPU istifadəsi | Kompilasiyada pik | Sabit |
JIT kompilasiyası yerləşdirmə sürəti və disk yerinə qənaət vacib olduqda üstünlüklidir. Mobil inkişaf kontekstində JIT tez-tez yenilənən proqramlar (A/B testi, hotfix) üçün idealdır. JIT həmçinin kodun gün ərzində dəfələrlə yenidən qurulduğu inkişaf mərhələsində rahatdır — kompilasiyaya qənaət edilən hər saniyə geribildirim dövrünü sürətləndirir.
JIT proqramçılara bir sıra praktiki üstünlüklər təmin edir. Birincisi — kiçik APK ölçüsü. JIT yanaşmasında APK-yə kompilasiya edilmiş native koddan 20–30% daha az yer tutan yalnız bayt kodu (DEX) yığılır. Məhdud daxili yaddaşı olan istifadəçilər üçün bu əhəmiyyətli üstünlükdür.
İkinci üstünlük — cihaza uyğunlaşma. JIT kodu real CPU arxitekturasını, RAM miqdarını və cari yükü nəzərə alaraq kompilasiya edir. Məsələn, 2 GB RAM-lı cihazda JIT daha az aqressiv kompilasiya edərək yaddaşa qənaət edə bilər, 12 GB-lıq flaqmanda isə bütün mümkün optimallaşdırmaları tətbiq edə bilər. AOT kompilasiyası isə əksinə, qərarı quraşdırma anında sabitləşdirir.
Bayt kodu platformadan müstəqil olaraq qalır ki, bu da proqramların yayılmasını asanlaşdırır. Bir APK ARM, ARM64 və x86 cihazlarında işləyir, JIT isə hər arxitektura üçün native kod yaradılmasını təmin edir. AOT yanaşması üçün ya APK-yə native kodun bir neçe variantını daxil etmək (ölçünü artırmaq), ya da hər arxitektura üçün ayrıca versiya kompilasiya etmək lazım olardı.
JIT-in əsas çatışmazlığı isinqəlmə gecikməsidir (warm-up delay). İstifadəçi JIT hot-metodları kompilasiya edərkən proqramın ilk saniyələrində yavaşlamalar görür. Oyunlarda bu, ilkin səviyyələrdə “kəkilmə” (stuttering) kimi özünü göstərir. Animasiyalı proqramlarda — ekranlar arası ilk keçidlərdə titrəmələr.
İkinci çatışmazlıq enerji istehlakıdır. Kompilasiya prosesi CPU-nu intensiv yükləyərək isinqəlmə dövründə enerji istehlakını 10–20% artırır. Batareya ilə işləyən cihazlarda bu, muxtar iş müddətini qısaldır. Xüsusilə tez-tez proqram yenidən başlatmaları olan ssenarilərdə nəzərə çarpır (məhdud yaddaş şəraitində çoxlu tapşırıq rejimi, sistem prosesləri boşaldıb yenidən yüklədikdə).
Digər problem JIT keşinin fraqmentasiyasıdır. Kompilasiya edilmiş kod fasiləsiz yaddaş sahəsində saxlanılır. Yeni siniflər yükləndikdə və əlavə metodlar kompilasiya edildikdə, keş fraqmentasiyaya uğrayır ki, bu da yaddaş idarəçiliyi üzərində əlavə yük yaradır. Dalvik-də bu problem keşin dövri təmizlənməsi ilə həll olunurdu; ART-də JIT keşi yığından ayrıca ayrılır və öz defraqmentasiya strategiyasından istifadə edir.
ART-də müasir yanaşma — hibrid kompilasiya, JIT və AOT-un güclü tərəflərini birləşdirir. Proqram quraşdırılarkən kompilasiya yerinə yetirilmir — yalnız bayt kodunun yoxlanılması (verify). Bu, sürətli quraşdırma və minimal yer tutmağı təmin edir. İlk işə salınmalar hot-metodların JIT kompilasiyası ilə interpretasiya rejimində işləyir — istifadəçi uzun gözləmə olmadan məqbul performans əldə edir.
Paralel olaraq real istifadə haqqında məlumat toplayan fon profilatoru işləyir. Proqramın 2–3 tam işə salınmasından sonra profil kifayət qədər tamlığa çatır və sistem native koda hot-metodları kompilasiya etmək üçün dex2oat-ı işə salır. Bu əməliyyat cihaz yüklənmədikdə (doldurulma, ekran söndürüldükdə) fonda yerinə yetirilir. Fon AOT tamamlandıqdan sonra proqram tam AOT kompilasiyasına bənzər performans əldə edir.
# Fon kompilasiyasının məcburi başlatılması
adb shell cmd package compile -m speed-profile -f com.example.app
# Kompilasiya statusuna baxış
adb shell cmd package dump-profiles com.example.app
Google I/O 2017 məlumatlarına görə, hibrid kompilasiya təmiz AOT ilə müqayisədə proqramların quraşdırma müddətini 30–50% qısaltmışdır. Sistem bölməsində tutulan yer 20–30% azalmışdır. Fon kompilasiyasından sonra performans tam AOT səviyyəsinə uyğun gəlir. Hibridin AOT-dan geri qaldığı yeganə ssenari quraşdırmadan dərhal sonra ilk işə salınmadır: proqram JIT rejimində işləyir və 10–15% yavaş ola bilər.
Tez-tez verilən suallar
JIT — proqramı sürətləndirmə üsuludur, burada kod əvvəlcədən deyil, iş zamanı hissə-hissə maşın dilinə tərcümə olunur. Ən tez-tez istifadə olunan hissələr kompilasiya edilir və keşlənir, nadir hissələr isə orijinal formada qalır.
JIT kodu icra zamanı kompilasiya edir ki, bu da yerə qənaət edir və quraşdırmanı sürətləndirir. AOT bütün kodu əvvəlcədən kompilasiya edir — proqram daha sürətli işə düşür, lakin diskdə daha çox yer və quraşdırma üçün daha çox vaxt tələb edir.
JIT silinməyib, təkamül edib. Android 5.0-da JIT-li Dalvik təmiz AOT ilə ART ilə əvəz olundu. Android 7.0-da JIT ART-ə hibrid sistemin bir hissəsi kimi qayıtdı, burada optimal performans üçün fon AOT kompilasiyası ilə birlikdə işləyir.
JIT CPU yükü səbəbindən isinqəlmə dövründə enerji istehlakını 10–20% artırır. Hot-metodların kompilasiyası tamamlandıqdan sonra enerji istehlakı normal səviyyəyə qayıdır. ART hibrid rejimi fon kompilasiyası sayəsində bu pik vəziyyətləri minimuma endirir.
Bəli, intensiv hesablama ssenarilərində. İstifadəçi proqramın ilk saniyələrində və ya oyunun əvvəlində yavaşlamalar görə bilər. Android-in müasir versiyalarında (8.0+) hibrid rejim profil edilmiş kompilasiya sayəsində bu effekti minimuma endirir.
Xülasə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun