Il runtime Android (ART) include un compilatore just-in-time (JIT) con profilazione del codice che migliora continuamente le prestazioni delle applicazioni Android durante l'esecuzione. Il compilatore JIT integra l'attuale compilatore AOT (ahead-of-time) di ART e migliora le prestazioni di runtime, risparmia spazio di archiviazione e velocizza gli aggiornamenti di applicazioni e sistema. Migliora inoltre il compilatore AOT evitando il rallentamento del sistema durante gli aggiornamenti automatici delle applicazioni o la ricompilatura delle applicazioni durante gli aggiornamenti over-the-air (OTA).
Sebbene JIT e AOT utilizzino lo stesso compilatore con un insieme simile di ottimizzazioni, il codice generato potrebbe non essere identico. Il codice JIT utilizza informazioni sul tipo di runtime, può eseguire un'inlining migliore e rende possibile la compilazione con sostituzione in pila (OSR), il tutto generando codice leggermente diverso.
Architettura JIT
Compilazione JIT
La compilazione JIT prevede le seguenti attività:
- L'utente esegue l'app, che attiva ART per caricare il file
.dex
.- Se il file
.oat
(il file AOT binario per il file.dex
) è disponibile, ART lo utilizza direttamente. Sebbene i file.oat
vengano generati regolarmente, non contengono sempre codice compilato (file binario AOT). - Se il file
.oat
non contiene codice compilato, ART viene eseguito tramite JIT e l'interprete per eseguire il file.dex
.
- Se il file
- La compilazione JIT è attivata per qualsiasi applicazione non compilata in base al
speed
filtro di compilazione (che indica "compila il più possibile dall'app"). - I dati del profilo JIT vengono scaricati in un file in una directory di sistema a cui solo l'applicazione può accedere.
- Il daemon AOT di compilazione (
dex2oat
) analizza questo file per avviarne la compilazione.
Figura 3. attività del daemon JIT.
Google Play Services è un esempio utilizzato da altre applicazioni che si comportano in modo simile alle librerie condivise.
Flusso di lavoro JIT
- Le informazioni di profilazione vengono memorizzate nella cache del codice e sottoposte alla raccolta del garbage in caso di pressione sulla memoria.
- Non vi è alcuna garanzia che uno snapshot acquisito quando l'applicazione era in background conterrà dati completi (ovvero tutto ciò di cui è stato eseguito JIT).
- Non viene fatto alcun tentativo per garantire che tutto venga registrato (in quanto ciò può influire sulle prestazioni di runtime).
- I metodi possono trovarsi in tre stati diversi:
- interpretato (codice DEX)
- Compilato JIT
- Compilato AOT
- Il requisito di memoria per eseguire il codice JIT senza influire sul rendimento dell'app in primo piano dipende dall'app in questione. Le app di grandi dimensioni richiedono più memoria rispetto alle app di piccole dimensioni. In genere, le app di grandi dimensioni si stabiliscono intorno ai 4 MB.
Attivare il logging JIT
Per attivare il logging JIT, esegui i seguenti comandi:
adb root
adb shell stop
adb shell setprop dalvik.vm.extra-opts -verbose:jit
adb shell start
Disattiva JIT
Per disabilitare JIT, esegui questi comandi:
adb root
adb shell stop
adb shell setprop dalvik.vm.usejit false
adb shell start
Forza compilazione
Per forzare la compilazione, esegui quanto segue:
adb shell cmd package compile
Casi d'uso comuni per la compilazione forzata di un pacchetto specifico:
- Basato sul profilo:
adb shell cmd package compile -m speed-profile -f my-package
- Completo:
adb shell cmd package compile -m speed -f my-package
Casi d'uso comuni per la compilazione forzata di tutti i pacchetti:
- In base al profilo:
adb shell cmd package compile -m speed-profile -f -a
- Completo:
adb shell cmd package compile -m speed -f -a
Cancellare i dati del profilo
Su Android 13 o versioni precedenti
Per cancellare i dati del profilo locale e rimuovere il codice compilato, esegui questo comando:
adb shell pm compile --reset
Su Android 14 o versioni successive
Per cancellare solo i dati del profilo locale:
adb shell pm art clear-app-profiles
Nota: a differenza del comando per Android 13 o versioni precedenti, questo comando non cancella i dati del profilo esterno (".dm") installati con l'app.
Per cancellare i dati del profilo locale e rimuovere il codice compilato generato dai dati del profilo locale (ovvero per ripristinare lo stato di installazione), esegui quanto segue:
adb shell pm compile --reset
Nota: questo comando non rimuove il codice compilato generato dai dati del profilo esterno (".dm") installati con l'app.
Per cancellare tutto il codice compilato, esegui questo comando:
adb shell cmd package compile -m verify -f
Nota: questo comando conserva i dati del profilo locale.