AOT — wat is het, Ahead-Of-Time compilatie en hoe het werkt

Auteur: IT Sectr Gepubliceerd: 2026-04-16 Leestijd: 9 min

AOT (Ahead-Of-Time) — compilatietechnologie waarbij broncode of bytecode voor het starten van het programma wordt omgezet in machine-instructies, in de bouw- of installatiefase. In Android werd AOT-compilatie de belangrijkste innovatie van de ART-uitvoeringsomgeving, die Dalvik verving in versie 5.0 Lollipop. Volgens gegevens van Google, 2024 elimineert AOT-compilatie in ART opwarmvertragingen en vermindert het energieverbruik van apps met 10–15% in vergelijking met de JIT-benadering.

Belangrijkste punten

  • AOT — Ahead-Of-Time compilatie: code omzetten in machinecode voordat het programma wordt gestart.
  • In Android wordt AOT uitgevoerd door het hulpprogramma dex2oat bij APK-installatie of op de achtergrond.
  • Het grootste voordeel van AOT — direct opstarten van apps zonder opwarmfase.
  • Nadeel — langere installatietijd en extra schijfruimte van 15–30%.
  • Moderne systemen gebruiken een hybride aanpak: JIT voor eerste keer opstarten, AOT voor hot-methoden.

Wat is AOT-compilatie?

Ahead-Of-Time (AOT) — een compilatiemethode waarbij het programma vóór het starten wordt omgezet in machinecode. De term „Ahead-Of-Time" staat tegenover JIT (Just-In-Time): als JIT „op het juiste moment" compileert, dan compileert AOT — „vooraf". De AOT-compiler ontvangt broncode of een tussenliggende representatie (bytecode) en genereert een uitvoerbaar bestand dat klaar is om te draaien.

De geschiedenis van AOT gaat terug naar traditionele C- en C++-compilers, waarbij compilatie altijd vóór het uitvoeren plaatsvindt. In de context van managed talen (Java, C#, Dart) is AOT een nieuwere innovatie: lange tijd werd gedacht dat dynamische mogelijkheden (reflectie, dynamisch laden van klassen) AOT moeilijk te implementeren maken. Google loste deze taak voor Android op door dex2oat te creëren — een AOT-compiler van DEX-bytecode naar native code.

Werkingsprincipe van AOT

De AOT-compiler voert een volledige vertaalcyclus uit. De eerste fase — parsen en bouwen van een abstracte syntaxisboom (AST). De tweede — analyse en optimalisatie: dode code verwijderen, inlining, lusoptimalisatie. De derde — het genereren van machinecode voor de doelarchitectuur (ARM, ARM64, x86). Het resultaat is een uitvoerbaar bestand dat geen verdere verwerking tijdens het uitvoeren vereist.

bash
# Handmatig starten van de AOT-compiler dex2oat
dex2oat --dex-file=classes.dex \
        --oat-file=classes.oat \
        --arch=arm64 \
        --instruction-set-variant=generic

# Controleren van het gecompileerde OAT-bestand
oatdump --oat-file=classes.oat --output=oat_dump.txt

AOT in Android: dex2oat en OAT-bestanden

In Android wordt AOT-compilatie geïmplementeerd via het hulpprogramma dex2oat (dalvik executable to optimized android translator). Wanneer een gebruiker een app installeert, start het systeem dex2oat, dat DEX-bestanden uit het APK leest, bytecode optimaliseert en een OAT-bestand maakt — een ELF-binair bestand met native code. Dit bestand wordt opgeslagen in de partitie /data/dalvik-cache/.

Het compilatieproces omvat meerdere niveaus van optimalisatie. Het basisniveau — bytecode-verificatie en basisoptimalisaties (dead code elimination, constant folding). Het gemiddelde — methoden inlining, loop unrolling, escape-analyse. Het maximale — globale optimalisaties van de hele app, inclusief devirtualisatie en optimalisatie van de stackgrootte. Het optimalisatieniveau hangt af van de compilatiemodus (speed, speed-profile, space).

Structuur van het OAT-bestand

Het OAT-bestand heeft het ELF-formaat (Executable and Linkable Format) — hetzelfde formaat dat native Linux-binary's gebruiken. In het OAT-bestand bevindt zich gecompileerde code voor elke methode van de app, evenals metadata: informatie over klassen, velden, methoden en relaties ertussen. ART gebruikt deze metadata voor snel laden van klassen en het oplossen van symbolische verwijzingen zonder volledig parsen van DEX.

OAT-componentDoel
ELF headerKoptekst van het ELF-formaat
Code sectionMachinecode van gecompileerde methoden
OAT headerART-metadata: versie, sectiegroottes
DEX sectionsOriginele DEX-gegevens voor reflectie
Link tableVerbindingstabel voor JNI en native bibliotheken

AOT vs JIT: vergelijkende analyse

AOT en JIT vertegenwoordigen verschillende punten in de ruimte van compromissen tussen prestaties en flexibiliteit. AOT biedt maximale uitvoeringssnelheid vanaf de eerste seconde, maar vereist meer schijfruimte en installatietijd. JIT bespaart ruimte en installatietijd, maar betaalt daarvoor met opwarmvertraging en piekenergieverbruik.

De belangrijkste factor bij de keuze — het gebruiksscenario. Voor apps die één keer worden gestart en lang draaien (games, editors, navigatie) heeft AOT de voorkeur — de compilatiekosten worden terugverdiend door stabiele prestaties. Voor kleine hulpprogramma's die zelden en kort worden gestart, kan JIT voordeliger zijn — snelle installatie en weinig ruimte zijn belangrijker dan piekprestaties.

CriteriumAOTJIT
OpstartenDirectMet opwarmen
InstallatieLanger (compilatie)Snel
Schijfruimte+15–30%Minimaal
EnergieverbruikStabielPieken bij compilatie
AanpasbaarheidLaagHoog

Codeprestaties

Een interessante nuance: AOT-code is niet altijd sneller dan JIT. JIT heeft toegang tot profielinformatie van de uitvoeringstijd — exacte objecttypen, aanroepfrequenties, echte vertakkingspatronen. Dit maakt optimalisaties mogelijk die niet beschikbaar zijn voor AOT (bijvoorbeeld profielgestuurd inlinen). In de praktijk bedraagt het verschil in prestaties van gecompileerde code tussen AOT en JIT ±5–10%, afhankelijk van het scenario.

Voordelen van AOT-compilatie

AOT biedt drie belangrijke voordelen voor mobiele apps. Ten eerste — voorspelbare prestaties. De gebruiker ziet geen 'haperingen' in de eerste seconden van gebruik: de app werkt op maximale snelheid vanaf het eerste frame. Dit is cruciaal voor games, animaties en interfaces met vloeiende overgangen.

Ten tweede — energie-efficiëntie. AOT creëert geen piekbelastingen van de CPU die kenmerkend zijn voor JIT-compilatie. De processor werkt in een stabiele modus, wat het energieverbruik met 10–15% vermindert in de eerste 30–60 seconden van de app. Voor een typische gebruiker die 20–30 apps per dag start, levert dit een merkbare toename van de batterijduur op.

Vereenvoudiging van de runtime

AOT-compilatie vereenvoudigt de runtime-omgeving. Wanneer alle code al is gecompileerd, is er geen behoefte meer aan een JIT-compiler, interpreter en profiler tijdens het uitvoeren. Dit verkleint de omvang van de runtime-omgeving zelf en verlaagt de kans op fouten. ART in volledige AOT-modus gebruikt ongeveer 15% minder RAM dan een vergelijkbare omgeving met actieve JIT.

Nadelen van AOT-compilatie

Het grootste nadeel van AOT — installatietijd. Op vroege apparaten met Android 5.0 kon de installatie van grote apps (100–200 MB) 2–5 minuten duren vanwege AOT-compilatie. Dit zorgde voor een negatieve gebruikerservaring: na het downloaden van het APK moest men wachten voordat de app kon worden geopend. Google loste dit probleem gedeeltelijk op in Android 7.0 door over te stappen op een hybride schema.

Het tweede nadeel — schijfruimte. OAT-bestanden zijn 15–30% groter dan de originele DEX-bestanden. Op apparaten met 8–16 GB ingebouwd geheugen 'eet' elke app extra ruimte op de systeempartitie. Voor gebruikers met veel geïnstalleerde apps (50–100) kan dit leiden tot ruimtegebrek voor systeemupdates.

Gebrek aan aanpasbaarheid

AOT-code wordt vastgelegd op het moment van compilatie. Als een app verschillende uitvoeringspatronen gebruikt afhankelijk van de Android-versie, apparaatmodel of gebruikersinstellingen, kan AOT zich niet aanpassen. Optimalisaties die voor het ene scenario zijn gekozen, kunnen suboptimaal zijn voor een ander. JIT is in dit opzicht flexibeler: het hercompileert hot-methoden wanneer de uitvoeringsomstandigheden veranderen.

AOT buiten Android: Flutter, .NET, Go

AOT-compilatie wordt niet alleen in Android gebruikt. Flutter gebruikt AOT voor het compileren van Dart-code naar native code voor iOS en Android. Dit garandeert UI-prestaties op het niveau van 60 fps, zelfs op zwakkere apparaten. In de ontwikkelfase gebruikt Flutter JIT (hot reload) en voor de release-build — AOT, waarbij de voordelen van beide benaderingen worden gecombineerd.

In het .NET-ecosysteem maakt de technologie ReadyToRun (R2R) het mogelijk om assemblies vooraf naar native code te compileren. Dit verkort de opstarttijd van .NET-apps met 30–50%. De Go-compiler is van nature een AOT-compiler: Go-programma's worden gecompileerd naar één statische binary zonder externe afhankelijkheden, wat ze ideaal maakt voor containeromgevingen.

dart
// Flutter: AOT-compilatie van Dart-code naar native code
// Release-build gebruikt AOT
flutter build apk --release

// Resultaat: libapp.so met AOT-gecompileerde Dart-code
// Ontwikkeling gebruikt JIT (hot reload)
flutter run

AOT en beveiliging

Een bijkomend voordeel van AOT — het bemoeilijken van reverse engineering. Gecompileerde native code is moeilijker te decompileren dan bytecode. Hulpprogramma's zoals JADX en APKTool werken met het DEX-formaat, maar kunnen de broncode niet uit OAT-bestanden herstellen op hetzelfde detailniveau. Dit vervangt obfuscatie (ProGuard, R8) niet, maar creëert een extra barrière voor analisten.

Hybride strategie: geprofileerde compilatie

De moderne standaard in Android — geprofileerde AOT-compilatie, geïmplementeerd in ART vanaf Android 7.0. Bij installatie wordt de app niet volledig gecompileerd — in plaats daarvan wordt snelle bytecode-verificatie en JIT gebruikt voor de eerste starts. Dit lost het probleem van lange installatietijd op dat kenmerkend was voor pure AOT in Android 5.0–6.0.

Na 2–3 keer starten van de app verzamelt de ART-profiler gegevens over het feitelijke gebruik en bepaalt welke methoden het meest kritisch zijn voor de prestaties. Vervolgens compileert dex2oat op de achtergrond (meestal 's nachts wanneer het apparaat wordt opgeladen) deze hot-methoden naar native code. Na achtergrondcompilatie bereikt de app prestaties die gelijkwaardig zijn aan volledige AOT, zonder negatieve invloed op de gebruikerservaring bij installatie.

kotlin
// Programmatisch beheer van compilatiemodus (Android 9+)
fun requestProfileCompilation(context: Context) {
    val pm = context.packageManager
    // Het wordt aanbevolen om geprofileerde compilatie te gebruiken
    pm.setComponentEnabledSetting(
        ComponentName(context, javaClass()),
        PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
        PackageManager.DONT_KILL_APP
    )
}

Optimalisatie voor hybride modus

Voor maximaal profijt van hybride compilatie moeten ontwikkelaars een aantal regels volgen. Gebruik basisprofielen (baseline profiles) — vooraf verzamelde profielen die samen met het APK worden geleverd en ART in staat stellen om onmiddellijk na installatie te beginnen met AOT-compilatie van hot-methoden. Baseline profiles verkorten de tijd tot het bereiken van volledige prestaties van 2–3 keer opstarten tot de eerste keer opstarten.

Veelgestelde vragen

Wat is AOT-compilatie in eenvoudige bewoordingen?

AOT — het vertalen van een programma naar machinecode vooraf, voordat de gebruiker het start. Stel je voor dat een boek volledig in het Nederlands is verteld voordat je het opent — je leest meteen, zonder vertraging voor het vertalen van pagina's.

Wat is het verschil tussen AOT en JIT?

AOT compileert code bij installatie (langere installatie, maar snellere start). JIT compileert code tijdens het uitvoeren (snelle installatie, maar de eerste seconden is de app trager). Moderne systemen combineren beide benaderingen.

Waarom is Android overgestapt van Dalvik naar ART met AOT?

Google wilde het probleem van JIT-opwarming elimineren — vertragingen in de eerste seconden van de app. AOT-compilatie in ART zorgde voor direct opstarten en verminderde het energieverbruik, wat cruciaal was voor mobiele apparaten.

Hoe beïnvloedt AOT de app-grootte?

De APK-grootte verandert niet — AOT-compilatie maakt OAT-bestanden op de systeempartitie die 15–30% groter zijn dan de originele DEX. De gebruiker ziet dit als een afname van de vrije ruimte in het ingebouwde geheugen, niet als een toename van de grootte van het te downloaden bestand.

Wat is geprofileerde AOT?

Dit is een hybride aanpak waarbij de eerste starts van de app JIT gebruiken en het systeem vervolgens op de achtergrond alleen veelgebruikte methoden naar native code compileert. Dit combineert de snelle installatie van JIT met de hoge prestaties van AOT.

Samenvatting

  • AOT (Ahead-Of-Time) — compilatie van bytecode naar machinecode vóór het starten van het programma, in de installatiefase.
  • In Android wordt AOT geïmplementeerd via het hulpprogramma dex2oat, dat ELF-binary's (OAT-bestanden) maakt.
  • De belangrijkste voordelen van AOT: direct opstarten, stabiele prestaties en laag energieverbruik.
  • De belangrijkste nadelen: langere installatietijd en extra schijfruimte van 15–30%.
  • AOT wordt niet alleen in Android gebruikt, maar ook in Flutter (Dart), .NET (R2R) en Go.
  • Moderne ART gebruikt geprofileerde AOT: JIT voor eerste starts, achtergrondcompilatie van hot-methoden.
  • Baseline profiles maken het mogelijk om AOT-compilatie van belangrijke methoden onmiddellijk na installatie van de app te starten.

We ontwikkelen een mobiele applicatie turnkey

IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.

Bespreek het project

Lees ook