AOT (Ahead-Of-Time) — technologie kompilace, při které se zdrojový kód nebo bytecode převádí na strojové instrukce před spuštěním programu, ve fázi sestavení nebo instalace. V Androidu se kompilace AOT stala klíčovou inovací běhového prostředí ART, které nahradilo Dalvik ve verzi 5.0 Lollipop. Podle údajů Google, 2024 eliminuje kompilace AOT v ART zpoždění zahřívání a snižuje spotřebu energie aplikací o 10–15% ve srovnání s přístupem JIT.
Hlavní body
Ahead-Of-Time (AOT) — metoda kompilace, při které se program převádí na strojový kód před jeho spuštěním. Termín „Ahead-Of-Time" stojí v protikladu k JIT (Just-In-Time): zatímco JIT kompiluje „právě včas", AOT — „předem". Kompilátor AOT na vstupu obdrží zdrojový kód nebo mezilehlou reprezentaci (bytecode) a vygeneruje spustitelný soubor připravený k běhu.
Historie AOT sahá k tradičním kompilátorům C a C++, kde se kompilace vždy provádí před spuštěním. V kontextu spravovaných jazyků (Java, C#, Dart) je AOT novější inovací: dlouho se mělo za to, že dynamické možnosti (reflexe, dynamické načítání tříd) činí AOT obtížně realizovatelným. Google vyřešil tento úkol pro Android vytvořením dex2oat — kompilátoru AOT bytecode DEX do nativního kódu.
Kompilátor AOT provádí úplný cyklus překladu. První fáze — parsování a sestavení abstraktního syntaktického stromu (AST). Druhá — analýza a optimalizace: odstranění mrtvého kódu, inlining, optimalizace cyklů. Třetí — generování strojového kódu pro cílovou architekturu (ARM, ARM64, x86). Výsledkem je spustitelný soubor, který nevyžaduje další zpracování za běhu.
# Ruční spuštění kompilátoru AOT dex2oat
dex2oat --dex-file=classes.dex \
--oat-file=classes.oat \
--arch=arm64 \
--instruction-set-variant=generic
# Kontrola zkompilovaného souboru OAT
oatdump --oat-file=classes.oat --output=oat_dump.txt
V Androidu je kompilace AOT implementována prostřednictvím nástroje dex2oat (dalvik executable to optimized android translator). Když uživatel instaluje aplikaci, systém spustí dex2oat, který přečte soubory DEX z APK, optimalizuje bytecode a vytvoří soubor OAT — ELF binárku s nativním kódem. Tento soubor je uložen v oddílu /data/dalvik-cache/.
Proces kompilace zahrnuje několik úrovní optimalizace. Základní úroveň — verifikace bytecode a základní optimalizace (dead code elimination, constant folding). Střední — inlining metod, loop unrolling, escape analýza. Maximální — globální optimalizace celé aplikace, včetně devirtualizace a optimalizace velikosti zásobníku. Úroveň optimalizace závisí na režimu kompilace (speed, speed-profile, space).
Soubor OAT má formát ELF (Executable and Linkable Format) — stejný formát, který používají nativní Linuxové binárky. Uvnitř souboru OAT se nachází zkompilovaný kód pro každou metodu aplikace a také metadata: informace o třídách, polích, metodách a vztazích mezi nimi. ART tato metadata používá pro rychlé načítání tříd a rozlišování symbolických odkazů bez úplného parsování DEX.
| Komponenta OAT | Účel |
|---|---|
| ELF header | Hlavička formátu ELF |
| Code section | Strojový kód zkompilovaných metod |
| OAT header | Metadata ART: verze, velikosti sekcí |
| DEX sections | Původní data DEX pro reflexi |
| Link table | Tabulka propojení pro JNI a nativní knihovny |
AOT a JIT představují různé body v prostoru kompromisů mezi výkonem a flexibilitou. AOT poskytuje maximální rychlost provádění od první sekundy, ale vyžaduje více místa na disku a času na instalaci. JIT šetří místo a čas instalace, ale platí za to zpožděním zahřívání a špičkovou spotřebou energie.
Klíčovým faktorem výběru je scénář použití. Pro aplikace, které se spouštějí jednou a běží dlouho (hry, editory, navigátory), je AOT výhodnější — náklady na kompilaci se vrátí díky stabilnímu výkonu. Pro malé nástroje, které se spouštějí zřídka a na krátkou dobu, může být JIT výhodnější — rychlá instalace a malé místo jsou důležitější než špičkový výkon.
| Kritérium | AOT | JIT |
|---|---|---|
| Spuštění | Okamžité | Se zahříváním |
| Instalace | Delší (kompilace) | Rychlá |
| Místo na disku | +15–30% | Minimální |
| Spotřeba energie | Stabilní | Špičky při kompilaci |
| Adaptabilita | Nízká | Vysoká |
Zajímavá nuance: Kód AOT není vždy rychlejší než JIT. JIT má přístup k profilovým informacím z běhu — přesným typům objektů, frekvenci volání, skutečným vzorům větvení. To umožňuje použít optimalizace nedostupné pro AOT (např. profilem řízený inlining). V praxi je rozdíl ve výkonu zkompilovaného kódu mezi AOT a JIT ±5–10% v závislosti na scénáři.
AOT poskytuje tři klíčové výhody pro mobilní aplikace. První — předvídatelný výkon. Uživatel nevidí „zasekávání" v prvních sekundách provozu: aplikace pracuje maximální rychlostí od prvního snímku. To je kritické pro hry, animace a rozhraní s plynulými přechody.
Druhá — energetická účinnost. AOT nevytváří špičkové zatížení CPU charakteristické pro kompilaci JIT. Procesor pracuje ve stabilním režimu, což snižuje spotřebu energie o 10–15% v prvních 30–60 sekundách provozu aplikace. Pro typického uživatele, který spouští 20–30 aplikací denně, to přináší znatelné zvýšení výdrže baterie.
Kompilace AOT zjednodušuje běhové prostředí. Když je veškerý kód již zkompilován, odpadá potřeba JIT kompilátoru, interpretru a profileru za běhu. To snižuje velikost samotného běhového prostředí a snižuje pravděpodobnost chyb. ART v režimu plného AOT zabírá přibližně o 15% méně RAM než analogické prostředí s aktivním JIT.
Hlavní nevýhoda AOT — doba instalace. Na raných zařízeních s Androidem 5.0 mohla instalace velkých aplikací (100–200 MB) trvat 2–5 minut kvůli kompilaci AOT. To vytvářelo negativní uživatelský zážitek: po stažení APK bylo nutné čekat, než bylo možné aplikaci otevřít. Google tento problém částečně vyřešil v Androidu 7.0 přechodem na hybridní schéma.
Druhou nevýhodou je zabrané místo. Soubory OAT jsou o 15–30% větší než původní soubory DEX. Na zařízeních s 8–16 GB vestavěné paměti každá aplikace „žere" další místo v systémovém oddílu. Pro uživatele s velkým počtem nainstalovaných aplikací (50–100) to může vést k nedostatku místa pro systémové aktualizace.
Kód AOT je fixován v okamžiku kompilace. Pokud aplikace používá různé vzory provádění v závislosti na verzi Androidu, modelu zařízení nebo uživatelských nastaveních, AOT se nemůže přizpůsobit. Optimalizace zvolené pro jeden scénář mohou být pro jiný neoptimální. JIT je v tomto ohledu flexibilnější: překompilovává hot-metody při změně podmínek provádění.
Kompilace AOT se používá nejen v Androidu. Flutter používá AOT pro kompilaci kódu Dart do nativního kódu pro iOS a Android. To zajišťuje výkon UI na úrovni 60 fps i na slabých zařízeních. Ve fázi vývoje Flutter používá JIT (hot reload) a pro release sestavení — AOT, čímž kombinuje výhody obou přístupů.
V ekosystému .NET technologie ReadyToRun (R2R) umožňuje kompilovat sestavení do nativního kódu předem. To zkracuje dobu spouštění .NET aplikací o 30–50%. Kompilátor Go je přirozeně kompilátor AOT: programy v Go jsou kompilovány do jednoho statického binárního souboru bez externích závislostí, což je činí ideálními pro kontejnerové prostředí.
// Flutter: kompilace AOT kódu Dart do nativního kódu
// Release sestavení používá AOT
flutter build apk --release
// Výsledek: libapp.so s AOT zkompilovaným kódem Dart
// Vývoj používá JIT (hot reload)
flutter run
Další výhodou AOT je ztížení reverzního inženýrství. Zkompilovaný nativní kód je obtížnější dekompilovat než bytecode. Nástroje jako JADX a APKTool pracují s formátem DEX, ale nemohou obnovit zdrojový kód ze souborů OAT na stejné úrovni podrobností. To nenahrazuje obfuskaci (ProGuard, R8), ale vytváří další překážku pro analytiky.
Moderní standard v Androidu — profilovaná kompilace AOT, implementovaná v ART od Androidu 7.0. Při instalaci není aplikace plně kompilována — místo toho se používá rychlá verifikace bytecode a JIT pro první spuštění. To řeší problém dlouhé instalace charakteristický pro čisté AOT v Androidu 5.0–6.0.
Po 2–3 spuštěních aplikace profiler ART shromažďuje údaje o skutečném používání a určuje, které metody jsou nejkritičtější pro výkon. Poté na pozadí (obvykle v noci, když se zařízení nabíjí) dex2oat kompiluje tyto hot-metody do nativního kódu. Po kompilaci na pozadí dosáhne aplikace výkonu odpovídajícího plnému AOT bez negativního dopadu na uživatelský zážitek při instalaci.
// Programové řízení režimu kompilace (Android 9+)
fun requestProfileCompilation(context: Context) {
val pm = context.packageManager
// Doporučuje se používat profilovanou kompilaci
pm.setComponentEnabledSetting(
ComponentName(context, javaClass()),
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP
)
}
Pro maximální užitek z hybridní kompilace by se vývojáři měli řídit několika pravidly. Používejte základní profily (baseline profiles) — předem shromážděné profily, které jsou dodávány spolu s APK a umožňují ART zahájit kompilaci AOT hot-metod ihned po instalaci. Baseline profiles zkracují dobu dosažení plného výkonu z 2–3 spuštění na první spuštění.
Často kladené otázky
AOT — překlad programu do strojového kódu předem, než jej uživatel spustí. Představte si, že kniha byla celá přeložena do češtiny, než jste ji otevřeli — čtete okamžitě, bez zpoždění na překládání stránek.
AOT kompiluje kód při instalaci (delší instalace, ale rychlejší spuštění). JIT kompiluje kód za běhu (rychlá instalace, ale první sekundy je aplikace pomalejší). Moderní systémy kombinují oba přístupy.
Google chtěl odstranit problém zahřívání JIT — zpoždění v prvních sekundách provozu aplikace. Kompilace AOT v ART zajistila okamžité spouštění a snížila spotřebu energie, což bylo kritické pro mobilní zařízení.
Velikost APK se nemění — kompilace AOT vytváří soubory OAT v systémovém oddílu, které jsou o 15–30% větší než původní DEX. Uživatel to vnímá jako snížení volného místa ve vestavěné paměti, nikoli jako zvětšení velikosti stahovaného souboru.
Je to hybridní přístup, při kterém první spuštění aplikace používají JIT a poté systém na pozadí kompiluje pouze často používané metody do nativního kódu. To kombinuje rychlou instalaci JIT s vysokým výkonem AOT.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také