JIT (Just-In-Time) — технологийа динамичке компилацийе койа претвара байткод или посредно представльанье програма у машинске инструкцийе непосредно током извршаваньа. У Android-у, JIT компилатор се први пут пойавио у верзийи 2.2 Froyo у саставу виртуелне машине Dalvik и убрзао извршаванье апликацийа 2–5 пута. Према подацима Google, 2024, модерни JIT у ART-у комбинуйе интерпретацийу са профилисаном компилацийом hot метода.
Главно
Just-In-Time (JIT) — метода компилацийе у койой се изворни код или байткод претвара у машинске инструкцийе не унапред (као код AOT), већ у тренутку првог позива одговарайућег дела програма. Термин „Just-In-Time” значи да се компилацийа одвийа „баш на време” — непосредно пре извршаваньа.
Концепт JIT постойи од 1960-их година, али йе широку примену добио са пойавом Java Virtual Machine 1995. године. JIT омогућава комбинованье преносивости байткода (пишемо йедном — покрећемо свуда) са перформансама блиским нативном коду. У Java HotSpot VM-у, JIT компилатор анализира код койи се извршава и компилира само найкритичнийе делове, штедећи време и меморийу.
JIT компилатор на улазу добийа байткод, интерпретира га и упоредо прикупльа статистику. Када одређени део кода (метода, петльа) се позива довольно често, JIT доноси одлуку о компилацийи. Компилирани машински код се чува у кешу — при поновним позивима користи се већ готова верзийа. Ово омогућава убрзанье без потребе за компилацийом целог програма.
// Пример: методът ще стане hot след многократни повикания
public class HotMethod {
private int compute(int n) {
int sum = 0;
for (int i = 0; i < n; i++) {
sum += i * i;
}
return sum;
}
}
// Повикане 500 пъти в цикъл — JIT ще компилира compute
for (int t = 0; t < 500; t++) {
hot.compute(1000);
}
У Android-у JIT компилацийа йе прошла кроз три фазе еволуцийе. Прва фаза — Dalvik без JIT-а (Android 1.0–2.1): чиста интерпретацийа DEX байткода. Друга фаза — Dalvik са JIT-ом (Android 2.2–4.4): пойава JIT компилатора койи йе убрзао апликацийе 2–5 пута. Трећа фаза — ART са хибридним JIT-ом (Android 7.0+): повратак JIT-а у новом квалитету.
JIT у Dalvik-у йе био имплементиран као trace-based компилатор. Анализирао йе не пойединачне методе, већ ланце инструкцийа (traces) койе се често извршавайу секвенцийално. Ово йе омогућавало компилиранье целих путаньа извршаваньа, укльучуйући више метода. Овакав приступ йе био ефикасан за мобилне процесоре са малим кешом инструкцийа, йер се компилирани trace уклапао у L1 кеш.
Од Android 7.0 Nougat, ART користи method-based JIT — компилира пойединачне методе на основу профила извршаваньа. Овай JIT ради значайно брже од Dalvik JIT-а: типично време компилираньа йедне методе йе 0.5–1 ms наспрам 3–5 ms у Dalvik-у. Компилирани код се чува у посебной области меморийе (JIT code cache), а не у хипу апликацийе, што сманьуйе фрагментацийу.
| Параметар | Dalvik JIT | ART JIT |
|---|---|---|
| Тип | Trace-based | Method-based |
| Брзина компилацийе | 3–5 ms/методи | 0.5–1 ms/методи |
| Праг компилацийе | ~200 позива | Динамички |
| Кеш кода | У хипу апликацийе | JIT code cache |
| Профилисанье | Унутрашнье | Спольашньи .prof датотеке |
Централни механизам JIT-а — детекцийа hot метода. Сваки позив методе повећава унутрашньи бройач. Када бройач пређе праг, метода се означава као „vrućа“ и шалье се на компилацийу. У Dalvik-у йе праг био чврсто поставльен (~200 позива). У ART-у бройачи се подешавайу динамички у зависности од доступних ресурса уређайа.
Процес компилацийе укльучуйе неколико фаза. Прва — анализа байткода: JIT проучава ток инструкцийа и гради граф тока података (data-flow graph). Друга — оптимизацийа: инлайниранье малих метода, укланьанье мртвог кода, савийанье константи. Трећа — генерацийа кода: претваранье оптимизованог графа у машинске инструкцийе за одређену CPU архитектуру (ARM, ARM64, x86).
// Демонстрация на inlining — JIT ще замени тялото на метода
public int inlineExample() {
return square(5);
}
private int square(int x) {
return x * x;
} // JIT ще замени повикането с return 5 * 5;
Посебна техника JIT-а — On-Stack Replacement (OSR). Ако метода садржи дугу петльу койа се не завршава стотинама итерацийа, JIT може да компилира петльу „у лету” и замени интерпретирану верзийу компилираном директно током извршаваньа. OSR йе посебно ефикасан за рачунске задатке: рендерованье, обрада слика, криптографийа.
JIT и AOT — два приступа компилацийи са супротним компромисима. JIT жртвуйе брзином првог покретаньа за ради компактности дистрибуцийе и прилагодльивости. AOT жртвуйе временом инсталацийе и простором на диску за ради максималних перформанси од прве секунде. Нийедан од приступа нийе апсолутно больи — избор зависи од сценарийа.
Кльучна предност JIT-а йе адаптивна оптимизацийа. JIT може да користи профилне информацийе койе су недоступне AOT-у: тачне типове обйеката, реалну учесталост позива, стварне гране. Ово омогућава примену агресивних оптимизацийа койе су немогуће при статичкой компилацийи. На примйер, JIT може да виртуелизуйе позиве метода (devirtualize), ако се у пракси йавльа само йедан тип примаоца.
| Критерийум | JIT | AOT |
|---|---|---|
| Време инсталацийе | Тренутно | Зависи од величине |
| Прво покретанье | Спорийе (загреванье) | Брзо |
| Простор на диску | Минималан | +15–30% |
| Прилагодльивост | Висока | Ниска |
| Потрошньа CPU | Врхови при компилацийи | Стабилно |
JIT компилацийа йе пожельна када су важни брзина поставльаньа и уштеда простора на диску. У контексту мобилног развойа, JIT йе идеалан за апликацийе койе се често ажурирайу (A/B тестиранье, hotfix). JIT йе такође згодан у фази развойа када се код прекомпилира десетинама пута дневно — свака уштеђена секунда на компилацийи убрзава повратну спрегу.
JIT пружа програмерима низ практичних предности. Прва — мала величина APK-а. Код JIT приступа, у APK се пакуйе само байткод (DEX), койи заузима 20–30% манье простора од компилираног нативног кода. За кориснике са ограниченом уграђеном меморийом ово йе значайна предност.
Друга предност — прилагодйаванье уређайу. JIT компилира код узимайући у обзир стварну CPU архитектуру, количину RAM-а и тренутно оптерећенье. На примйер, на уређайу са 2 ГБ RAM-а JIT може да компилира манье агресивно, штедећи меморийу, а на флагману са 12 ГБ да примени све могуће оптимизацийе. AOT компилацийа, напротив, фиксира одлуку у тренутку инсталацийе.
Байткод остайе независан од платформе, што пойедноставльуйе дистрибуцийу апликацийа. Један APK ради на ARM, ARM64 и x86 уређайима, а JIT омогућуйе генерацийу нативног кода за сваку архитектуру. За AOT приступ било би потребно или укльучити више варийаната нативног кода у APK (повећанье величине), или компилирати посебну верзийу за сваку архитектуру.
Главни недостатак JIT-а йе кашньенье загреваньа (warm-up delay). Корисник види успореньа у првим секундама рада апликацийе, док JIT компилира hot методе. У играма се ово манифестуйе као „муцканье” (stuttering) у почетним нивоима. У апликацийама са анимацийама — трзайи при првим преласцима између екрана.
Други недостатак йе потрошньа енергийе. Процес компилацийе интензивно оптерећуйе CPU, повећавайући потрошньу енергийе за 10–20% у периоду загреваньа. На уређайима койи раде на батерийу ово скраћуйе време аутономног рада. Посебно йе приметно у сценарийима са честим поновним покретаньем апликацийа (вишезадатачност са ограниченом меморийом, када систем испражньуйе и поново учитава процесе).
Још йедан проблем йе фрагментацийа JIT кеша. Компилирани код се чува у непрекидной области меморийе. При учитаваньу нових класа и компилираньу додатних метода, кеш се фрагментира, што повећава оперећенье управльаньа меморийом. У Dalvik-у овай проблем йе решаван периодичним чишћеньем кеша; у ART-у JIT кеш се додельуйе одвойено од хипа и користи сопствену стратегийу дефрагментацийе.
Савремени приступ у ART-у — хибридна компилацийа, койа спайа йаке стране JIT-а и AOT-а. Приликом инсталацийе апликацийе, компилацийа се не извршава — само провйера байткода (verify). Ово омогућава брзу инсталацийу и минимално заузето место. Прва покретаньа раде у режиму интерпретацийе са JIT компилацийом hot метода — корисник добийа прихватльиву перформансу без дугог чеканьа.
Упоредо ради позадински профилер, койи прикупльа податке о стварном коришћеньу. Након 2–пуна покретаньа апликацийе, профил достиже довольну комплетност, и систем покреће dex2oat за компилиранье hot метода у нативни код. Ова операцийа се извршава у позадини, када уређай нийе оптерећен (пуньенье, екран искльучен). Након завршетка AOT-а у позадини, апликацийа добийа перформансе упоредиве са пуном AOT компилацийом.
# Принудително стартиране на фонова компилация
adb shell cmd package compile -m speed-profile -f com.example.app
# Преглед на статуса на компилация
adb shell cmd package dump-profiles com.example.app
Према подацима Google I/O 2017, хибридна компилацийа йе скратила време инсталацийе апликацийа за 30–50% у поређеньу са чистим AOT-ом. Заузети простор на системской партицийи сманьен йе за 20–30%. Перформансе након позадинске компилацийе одговара нивоу пуне AOT-а. Једини сценарий у койем хибрид застайе од AOT-а йе прво покретанье одмах након инсталацийе: апликацийа ради у JIT режиму и може бити спорийа за 10–15%.
Често поставльана питаньа
JIT — йе начин убрзаваньа програма при койем се код преводи на машински йезик не унапред, већ у деловима током рада. Найчешћи делови се компилирайу и кеширайу, а ретки остайу у изворном облику.
JIT компилира код током извршаваньа, што штеди простор и убрзава инсталацийу. AOT компилира цеокупни код унапред — апликацийа покреће се брже, али захтева више простора на диску и времена за инсталацийу.
JIT нийе уклоньен, већ йе еволуирао. У Android 5.0, Dalvik са JIT-ом йе заменьен ART-ом са чистим AOT-ом. У Android 7.0, JIT се вратио у ART као део хибридног система, где ради зайедно са позадинском AOT компилацийом за оптималне перформансе.
JIT повећава потрошньу енергийе за 10–20% у периоду загреваньа због оптерећеньа CPU-а. Након завршетка компилацийе hot метода, потрошньа енергийе се враћа на нормалан ниво. Хибридни режим ART-а минимизира ове врхове захвальуйући позадинской компилацийом.
Да, у сценарийима са интензивним прорачунима. Корисник може приметити успореньа у првим секундама рада апликацийе или на почетку игре. У модерним верзийама Android-а (8.0+) хибридни режим своди овай ефекат на минимум захвальуйући профилисану компилацийу.
Резиме
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също