Implémenter le compilateur ART juste-à-temps

Android Runtime (ART) inclut un compilateur juste-à-temps (JIT) avec un profilage de code qui améliore continuellement les performances des applications Android pendant leur exécution. Le compilateur JIT complète le compilateur AOT actuel d'ART et améliore les performances d'exécution, économise de l'espace de stockage et accélère les mises à jour des applications et du système. Il améliore également le compilateur AOT en évitant le ralentissement du système lors des mises à jour automatiques des applications ou de la recompilation des applications lors des mises à jour Over The Air (OTA).

Bien que JIT et AOT utilisent le même compilateur avec un ensemble d'optimisations similaire, le code généré peut ne pas être identique. Le JIT utilise des informations de type d'exécution, peut effectuer une meilleure imbrication et permet la compilation par remplacement de pile (OSR), ce qui génère un code légèrement différent.

Architecture JIT

Architecture JIT
Figure 1 Architecture JIT.

Compilation JIT

La compilation JIT implique les activités suivantes:

Composition guidée par le profil
Figure 2. Compilation guidée par le profil
  1. L'utilisateur exécute l'application, ce qui déclenche ensuite ART pour charger le fichier .dex.
    • Si le fichier .oat (le binaire AOT pour le fichier .dex) est disponible, ART l'utilise directement. Bien que les fichiers .oat soient générés régulièrement, ils ne contiennent pas toujours du code compilé (binaire AOT).
    • Si le fichier .oat ne contient pas de code compilé, ART s'exécute via le JIT et l'interprète pour exécuter le fichier .dex.
  2. La compilation JIT est activée pour toute application qui n'est pas compilée conformément au filtre de compilation speed (qui indique "compiler autant que possible à partir de l'application").
  3. Les données de profil JIT sont vidées dans un fichier situé dans un répertoire système auquel seule l'application peut accéder.
  4. Le daemon de compilation AOT (dex2oat) analyse ce fichier pour lancer sa compilation.

    Daemon JIT
    Figure 3. Activités du daemon JIT.

Le service Google Play est un exemple utilisé par d'autres applications qui se comportent comme les bibliothèques partagées.

Workflow JIT

Architecture JIT
Figure 4. Flux de données JIT.
  • Les informations de profilage sont stockées dans le cache de code et soumises à la collecte des déchets en cas de pression sur la mémoire.
    • Il n'est pas garanti qu'un instantané pris lorsque l'application était en arrière-plan contienne des données complètes (c'est-à-dire tout ce qui a été JIT).
    • Aucune tentative n'est faite pour s'assurer que tout est enregistré (car cela peut avoir un impact sur les performances d'exécution).
  • Les méthodes peuvent être associées à trois états différents :
    • interprété (code DEX)
    • Compilation JIT
    • Compilation anticipée (ou "compilation AOT")
    Si le code JIT et le code AOT existent (par exemple, en raison de dé-optimisations répétées), le code JIT est privilégié.
  • La quantité de mémoire requise pour exécuter le JIT sans affecter les performances de l'application au premier plan dépend de l'application en question. Les applications volumineuses nécessitent plus de mémoire que les petites applications. En règle générale, les applications volumineuses se stabilisent autour de 4 Mo.

Activer la journalisation JIT

Pour activer la journalisation JIT, exécutez les commandes suivantes:

adb root
adb shell stop
adb shell setprop dalvik.vm.extra-opts -verbose:jit
adb shell start

Désactiver le JIT

Pour désactiver le JIT, exécutez les commandes suivantes:

adb root
adb shell stop
adb shell setprop dalvik.vm.usejit false
adb shell start

Forcer la compilation

Pour forcer la compilation, exécutez la commande suivante:

adb shell cmd package compile

Cas d'utilisation courants de la compilation forcée d'un package spécifique:

  • Basée sur le profil:
    adb shell cmd package compile -m speed-profile -f my-package
    
  • Complet:
    adb shell cmd package compile -m speed -f my-package
    

Cas d'utilisation courants de la compilation forcée de tous les packages:

  • Basé sur les profils:
    adb shell cmd package compile -m speed-profile -f -a
    
  • Complet:
    adb shell cmd package compile -m speed -f -a
    

Effacer les données du profil

Sur Android 13 ou version antérieure

Pour effacer les données de profil locales et supprimer le code compilé, exécutez la commande suivante:

adb shell pm compile --reset 

Sur Android 14 ou version ultérieure

Pour effacer les données de profil locales uniquement:

adb shell pm art clear-app-profiles 

Remarque: Contrairement à la commande pour Android 13 ou version antérieure, cette commande n'efface pas les données de profil externes (".dm") installées avec l'application.

Pour effacer les données de profil local et supprimer le code compilé généré à partir des données de profil local (c'est-à-dire pour rétablir l'état d'installation), exécutez la commande suivante:

adb shell pm compile --reset 

Remarque: Cette commande ne supprime pas le code compilé généré à partir de données de profil externes (".dm") installées avec l'application.

Pour effacer tout le code compilé, exécutez la commande suivante:

adb shell cmd package compile -m verify -f 

Remarque: Cette commande conserve les données de profil locales.