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. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође