Android Runtime (ART) — de runtime-omgeving voor Android-apps, geïntroduceerd in Android 5.0 Lollipop als vervanging van Dalvik. De belangrijkste innovatie — voorafgaande AOT-compilatie van DEX-bytecode naar native machinecode direct bij installatie van de app, waardoor het jarenlange probleem van het opwarmen van de JIT-compiler werd opgelost. Volgens Google, 2024 levert ART een prestatieverbetering van 20–30% in vergelijking met Dalvik met behoud van volledige achterwaartse compatibiliteit met het DEX-formaat.
Belangrijkste punten
Android Runtime (ART) — de runtime-omgeving die DEX-bytecode compileert naar native machinecode voordat deze wordt uitgevoerd. In tegenstelling tot Dalvik, dat Just-In-Time-compilatie gebruikte tijdens het uitvoeren, voert ART Ahead-Of-Time (AOT)-compilatie uit bij installatie van de APK. Deze fundamentele architectuurverandering leidde tot aanzienlijke versnelling van apps en lager energieverbruik.
ART verscheen voor het eerst als experimentele optie in Android 4.4 KitKat. Ontwikkelaars konden het inschakelen in de ontwikkelaarsinstellingen en hun apps testen. In Android 5.0 Lollipop werd ART de standaard runtime-omgeving en werd Dalvik volledig verwijderd uit het platform. Tegen de tijd van Android 7.0 Nougat kreeg ART een hybride compilatiemodus.
De beslissing om Dalvik te vervangen door ART was niet plotseling. Het werk aan de nieuwe omgeving begon in 2012, toen Google de beperkingen van de JIT-aanpak inzag. Hoofddoelen: het versnellen van het opstarten van apps, het verminderen van de processorbelasting en het verlagen van het energieverbruik. De ontwikkeling werd geleid door het team Android Runtime Group, dat eerder aan Dalvik-optimalisaties had gewerkt.
ART gebruikt dezelfde registerarchitectuur als Dalvik, maar met een volledig herontworpen compiler. In plaats van een interpreter en JIT-compiler bevat ART de AOT-compiler dex2oat, die DEX-bestanden bij installatie omzet in ELF-binary's. Als gevolg hiervan start een app op ART onmiddellijk met native prestaties, zonder opwarmfase.
ART behield de belangrijkste principes van Dalvik: isolatie van apps via aparte processen, registerarchitectuur en ondersteuning van het DEX-formaat. De interne implementatie werd echter volledig herschreven. In plaats van de Dalvik-interpreter bevat ART drie uitvoeringsmodi: interpreter, JIT-compiler en AOT-compiler dex2oat. De moduskeuze hangt af van de fase van de levenscyclus van de app.
Het belangrijkste onderdeel van ART — dex2oat (dalvik executable to optimized android translator). Deze tool wordt gestart bij installatie van de app (sinds Android 7.0 — ook bij achtergrondoptimalisatie). dex2oat leest DEX-bestanden uit de APK, optimaliseert bytecode en genereert een OAT-bestand — een ELF-binary met native code. OAT-bestanden worden opgeslagen in de map /data/dalvik-cache/.
# OAT-bestanden op het apparaat controleren
adb shell ls -la /data/dalvik-cache/arm64/
# Geforceerde hercompilatie van de app
adb shell cmd package compile -m speed com.example.app
Het ART-systeem bestaat uit verschillende onderling verbonden modules. De compiler dex2oat is verantwoordelijk voor het genereren van native code. De garbage collector (GC) beheert het vrijmaken van geheugen. De interpreter voert zelden aangeroepen code uit zonder compilatie. De profiler volgt hot-methoden voor hybride compilatie. Elke module kan onafhankelijk werken, wat ART flexibel en schaalbaar maakt.
Sinds Android 7.0 Nougat gebruikt ART een hybride benadering van compilatie, die de voordelen van JIT en AOT combineert. Bij installatie van de app voert ART geen volledige AOT-compilatie meer uit — in plaats daarvan start de app in geïnterpreteerde modus met JIT-compilatie van hot-methoden. Dit verkort de installatietijd en de benodigde opslagruimte.
Parallel werkt achtergrondprofiler (background profiler). Het verzamelt uitvoeringsstatistieken: welke methoden het vaakst worden aangeroepen, welke codetakken worden uitgevoerd, welke klassen worden geladen. Na voldoende gegevensverzameling (meestal na 2–3 keer starten van de app) start ART dex2oat op de achtergrond en compileert alleen geprofileerde hot-methoden naar native code.
ART ondersteunt verschillende compilatiemodi die worden beheerd via system_server. Modus "speed" compileert alle methoden naar AOT (maximale prestaties, lange installatie). Modus "speed-profile" compileert alleen geprofileerde hot-methoden (balans tussen snelheid en grootte). Modus "verify" controleert alleen de bytecode zonder compilatie (minimale ruimte, interpretatie). Standaard wordt speed-profile gebruikt — optimaal voor de meeste apps.
| Modus | Compilatie | Installatietijd | Prestaties |
|---|---|---|---|
| speed | Volledige AOT | Lang | Maximaal |
| speed-profile | Geprofileerde AOT | Snel | Hoog |
| verify | Zonder compilatie | Direct | Interpretatie |
| space | Minimale AOT | Gemiddeld | Gemiddeld |
De profiler verzamelt uitvoeringsgegevens in speciale .prof-bestanden. Elke app slaat zijn profiel op in /data/misc/profiles/. Bij het bereiken van de drempel (meestal 1000 samples) start de profiler dex2oat om geïdentificeerde hot-methoden te compileren. Profielen blijven behouden tussen app-updates, wat heroptimalisatie na OTA-systeemupdates versnelt.
Garbage collection in ART is drastisch verbeterd in vergelijking met Dalvik. In plaats van een single-threaded Concurrent Mark and Sweep (CMS) gebruikt ART een generationele collector met verschillende optimalisaties: moving collector (heap-compactie), large object space (aparte opslag van grote objecten) en concurrent compaction (parallelle compactie).
Een typische GC-pauze in ART is 2–3 ms tegenover 5–10 ms in Dalvik. Dit werd mogelijk dankzij verschillende mechanismen. Ten eerste gebruikt ART read-barrier in plaats van stop-the-world voor concurrent-fasen. Ten tweede verwerkt de generationele collector in de meeste cycli alleen de jonge generatie objecten, zonder de hele heap aan te tasten. Ten derde wordt large object space (LOS) apart toegewezen en neemt niet deel aan normale GC-cycli.
// GC-logboeken inschakelen voor debugging
System.logV("ART", "GC trigger: allocation failed");
// Geforceerde GC-aanroep (niet aanbevolen in productie)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Debug.getRuntimeIStats();
}
Ondanks de verbeterde GC blijven geheugenlekken een actueel probleem. Een ART-specifieke oorzaak — het laden van native bibliotheken via JNI zonder correct vrijgeven. Als native code geheugen toewijst via malloc maar free niet aanroept, kan ART dit geheugen niet vrijgeven — het bevindt zich buiten de beheerde heap. De tool AddressSanitizer in Android NDK helpt bij het opsporen van dergelijke lekken.
ART en Dalvik zijn twee fundamenteel verschillende implementaties van dezelfde taak: het uitvoeren van Android-apps. De verschillen hebben invloed op alle niveaus: van compilatie tot geheugenbeheer. Hieronder vindt u een vergelijking op basis van belangrijke prestatie- en compatibiliteitsparameters.
Het belangrijkste voordeel van ART — eliminatie van JIT-opwarming. Op Dalvik kon een app de eerste 3–10 seconden trager zijn terwijl JIT hot-methoden compileerde. Op ART zijn alle methoden al gecompileerd naar native code (of worden ze op de achtergrond gecompileerd). Dit is vooral merkbaar in games en apps met een zware UI: het verschil in fps kan 15–20% bedragen in het voordeel van ART.
| Parameter | Dalvik | ART |
|---|---|---|
| Compilatie | JIT (tijdens uitvoering) | AOT + hybride (bij installatie) |
| Opstarttijd | 3–10 s (opwarming) | Direct |
| APK-grootte | ~6–7 MB (DEX) | +20% (OAT) |
| GC-pauzes | 5–10 ms | 2–3 ms |
| Energieverbruik | Hoger (JIT belast CPU) | Lager (native code) |
Alle apps die voor Dalvik zijn geschreven, werken op ART zonder wijzigingen. Google garandeert volledige achterwaartse compatibiliteit op DEX-bytecode-niveau. Uitzondering — code die Dalvik-specifieke interne API's gebruikt via reflectie: leden van de klasse dalvik.system.DexFile die zijn gemarkeerd met @hide in de Android SDK. Dergelijke code moet worden bijgewerkt om openbare API's te gebruiken.
ART werd de eerste Android-runtime met native ondersteuning voor Java 8-functies. Sinds Android 7.0 bevat ART desugaring — het proces van het omzetten van Java 8-constructies (lambda's, method references, Stream API) naar equivalente Java 7-code. Dit maakt het mogelijk moderne syntax te gebruiken zonder compatibiliteit met oudere apparaten te verliezen.
Desugaring wordt uitgevoerd door de D8-compiler en werkt als volgt. Broncode met een lambda wordt omgezet in een synthetische methode binnen dezelfde klasse, en de lambda wordt vervangen door een invoke-custom-aanroep. ART's runtime ondersteunt de invoke-custom-instructie, speciaal toegevoegd voor Java 8. Op apparaten met Android 6.0 en lager worden lambda's gedesugard naar anonieme klassen.
// Java 8 lambda — desugaring in ART
button.setOnClickListener(v -> handleClick(v));
// Na desugaring (equivalent in Java 7)
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handleClick(v);
}
});
Niet alle Java 8-functies worden ondersteund door desugaring. De java.time-API (datum en tijd) is alleen toegankelijk via desugar_jdk_libs — een extra bibliotheek die wordt toegevoegd in build.gradle. Stream API vereist ook desugar_jdk_libs. java.util.function en Optional werken zonder extra afhankelijkheden. Volledige Java 8-ondersteuning is beschikbaar op apparaten met Android 8.0 en hoger zonder desugaring.
Hoewel ART achterwaarts compatibel is, verbeteren sommige optimalisatiepraktijken de prestaties juist in deze omgeving. De belangrijkste aanbeveling — minimaliseer reflectie. ART compileert methoden die zichtbaar zijn in de compilatiefase naar een directe machinecode-aanroep. Reflectie dwingt ART extra stubs te genereren, wat de uitvoering met 10–15% vertraagt.
Sinds Android 9.0 heeft ART ondersteuning voor App Startup Optimization. De ontwikkelaar kan initialisatieklassen in het manifest markeren via <initialization>, en ART zal ze vooraf laden bij het starten van de app. Dit verkort de opstarttijd met 5–15% voor apps met veel plugins of bibliotheken.
<!-- App Startup Optimization in AndroidManifest.xml -->
<application>
<profileable
android:shell="true"
android:enable="true" />
</application>
Gebruik voor het meten van prestaties op ART systrace en perfetto. Systrace toont de compilatietijd van dex2oat, GC-frequentie en framesnelheid. Perfetto geeft meer gedetailleerde informatie: threadverdeling, JNI-overgangstijd, laden van native bibliotheken. Start: adb shell perfetto -o /data/misc/perfetto-traces/trace.perfetto -t 10s sched freq idle am wm.
Veelgestelde vragen
ART (Android Runtime) — de runtime-omgeving voor Android-apps die de code van de app compileert naar machinecode bij installatie. Dit versnelt het starten en werken van apps in vergelijking met de oude Dalvik-omgeving.
ART compileert code vooraf (AOT) bij installatie van de app, terwijl Dalvik deze in delen compileerde tijdens het uitvoeren (JIT). Daarom starten apps op ART sneller en verbruiken ze minder energie.
Voer adb shell getprop uit en zoek de eigenschap persist.sys.dalvik.vm.lib.2. Waarde "libart.so" betekent ART, "libdvm.so" — Dalvik. Op alle apparaten met Android 5.0+ is ART de runtime-omgeving.
Enigszins. De app zelf blijft in APK-formaat met DEX-bestanden. ART maakt een extra OAT-bestand aan in /data/dalvik-cache/, dat 10–20% meer ruimte inneemt dan de originele DEX, maar deze opslag maakt geen deel uit van de APK-grootte.
Ja, ART ondersteunt de meeste Java 8-functies via het desugaring-mechanisme. Lambda's, method references en functionele interfaces werken op alle apparaten met Android 5.0+. Voor Stream API en java.time is de bibliotheek desugar_jdk_libs vereist.
Samenvatting
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.
Lees ook