Configuration de l'ART

Restez organisé à l'aide des collections Enregistrez et classez les contenus selon vos préférences.

Cette page explique comment configurer ART et ses options de compilation. Les sujets abordés ici incluent la configuration de la pré-compilation de l'image système, les options de compilation dex2oat et comment échanger l'espace de partition système, l'espace de partition de données et les performances.

Voir ART et Dalvik , le format exécutable Dalvik et les pages restantes sur source.android.com pour travailler avec ART. Consultez Vérification du comportement des applications sur Android Runtime (ART) pour vous assurer que vos applications fonctionnent correctement.

Comment fonctionne l'ART

ART utilise une compilation anticipée (AOT) et, à partir d'Android 7.0 (Nougat ou N), il utilise une combinaison hybride d'AOT, de compilation juste-à-temps (JIT) et de compilation guidée par profil. La combinaison de tous ces modes de compilation est configurable et sera abordée dans cette section. Par exemple, les appareils Pixel sont configurés avec le flux de compilation suivant :

  1. Une application est initialement installée sans aucune compilation AOT. Les premières fois que l'application s'exécute, elle est interprétée et les méthodes fréquemment exécutées sont compilées JIT.
  2. Lorsque l'appareil est inactif et en charge, un démon de compilation s'exécute pour compiler AOT le code fréquemment utilisé en fonction d'un profil généré lors des premières exécutions.
  3. Le prochain redémarrage d'une application utilise le code guidé par le profil et évite de faire une compilation JIT à l'exécution pour les méthodes déjà compilées. Les méthodes qui sont compilées JIT lors des nouvelles exécutions sont ajoutées au profil, qui sera ensuite récupéré par le démon de compilation.

ART comprend un compilateur (l'outil dex2oat ) et un runtime ( libart.so ) qui est chargé pour démarrer le Zygote. L'outil dex2oat prend un fichier APK et génère un ou plusieurs fichiers d'artefact de compilation que le runtime charge. Le nombre de fichiers, leurs extensions et leurs noms sont susceptibles de changer d'une version à l'autre, mais à partir de la version Android 8, les fichiers générés sont :

  • .vdex : contient le code DEX non compressé de l'APK, avec quelques métadonnées supplémentaires pour accélérer la vérification.
  • .odex : contient le code compilé AOT pour les méthodes dans l'APK.
  • .art (optional) : contient des représentations internes ART de certaines chaînes et classes répertoriées dans l'APK, utilisées pour accélérer le démarrage de l'application.

Options de compilation

Les options de compilation pour ART sont de deux catégories :

  1. Configuration de la ROM système : quel code est compilé par AOT lors de la création d'une image système.
  2. Configuration d'exécution : comment ART compile et exécute des applications sur un appareil.

L'une des principales options ART pour configurer ces deux catégories est les filtres du compilateur . Les filtres du compilateur déterminent la manière dont ART compile le code DEX et constituent une option transmise à l'outil dex2oat . À partir d'Android 8, il existe quatre filtres officiellement pris en charge :

  • verify : n'exécute que la vérification du code DEX.
  • quicken : (supprimé depuis Android 12) exécutez la vérification du code DEX et optimisez certaines instructions DEX pour obtenir de meilleures performances de l'interpréteur.
  • speed : exécutez la vérification du code DEX et compilez toutes les méthodes AOT.
  • speed-profile : exécute la vérification du code DEX et les méthodes de compilation AOT répertoriées dans un fichier de profil.

Configuration de la ROM système

Il existe un certain nombre d'options de construction ART disponibles pour configurer une ROM système. La configuration de ces options dépend de l'espace de stockage disponible pour l'image système et du nombre d'applications préinstallées. Les fichiers JAR/APK compilés dans une ROM système peuvent être divisés en quatre catégories :

  • Code de chemin de classe de démarrage : compilé avec le filtre de compilateur speed-profile par défaut.
  • Code du serveur système (voir PRODUCT_SYSTEM_SERVER_JARS , PRODUCT_APEX_SYSTEM_SERVER_JARS , PRODUCT_STANDALONE_SYSTEM_SERVER_JARS , PRODUCT_APEX_STANDALONE_SYSTEM_SERVER_JARS plus loin dans ce document) :
    • (depuis Android 14 (AOSP expérimental)) compilé avec le filtre du compilateur speed-profile par défaut, ou compilé avec le filtre du compilateur de speed si aucun profil n'est fourni.
    • (jusqu'à Android 13) compilé avec le filtre du compilateur de speed par défaut.
    Configurable via PRODUCT_SYSTEM_SERVER_COMPILER_FILTER (voir plus loin dans ce document).
  • Applications principales spécifiques au produit (voir PRODUCT_DEXPREOPT_SPEED_APPS plus loin dans ce document) : compilées avec le filtre du compilateur de speed par défaut.
  • Toutes les autres applications : compilées avec le filtre de compilateur speed-profile par défaut, ou compilées avec le filtre de compilateur de verify si aucun profil n'est fourni.

    Configurable via PRODUCT_DEX_PREOPT_DEFAULT_COMPILER_FILTER (voir plus loin dans ce document).

Options de makefile

  • WITH_DEXPREOPT
  • Indique si dex2oat est appelé sur le code DEX installé sur l'image système. Activé par défaut.

  • DONT_DEXPREOPT_PREBUILTS (depuis Android 5)
  • L'activation DONT_DEXPREOPT_PREBUILTS empêche les pré-construits d'être pré-optimisés. Ce sont des applications qui include $(BUILD_PREBUILT) spécifié dans leur Android.mk . Ignorer la pré-optimisation des applications prédéfinies susceptibles d'être mises à jour via Google Play permet d'économiser de l'espace dans l'image système, mais augmente le temps de premier démarrage. Notez que cette option n'a aucun effet sur les applications prédéfinies définies dans Android.bp .

  • PRODUCT_DEX_PREOPT_DEFAULT_COMPILER_FILTER (depuis Android 9)
  • PRODUCT_DEX_PREOPT_DEFAULT_COMPILER_FILTER spécifie le filtre de compilateur par défaut pour les applications pré-optimisées. Ces applications sont définies dans Android.bp ou include $(BUILD_PREBUILT) spécifié dans leur Android.mk . Si elle n'est pas spécifiée, la valeur par défaut est speed-profile , ou verify si la valeur n'est pas spécifiée et qu'aucun profil n'est fourni.

  • WITH_DEXPREOPT_BOOT_IMG_AND_SYSTEM_SERVER_ONLY (nouveau dans Android 8 MR1)
  • L'activation WITH_DEXPREOPT_BOOT_IMG_AND_SYSTEM_SERVER_ONLY pré-optimise uniquement le chemin de classe de démarrage et les jars du serveur système.

  • LOCAL_DEX_PREOPT
  • La pré-optimisation peut également être activée ou désactivée sur une base d'application individuelle en spécifiant l'option LOCAL_DEX_PREOPT dans la définition du module. Cela peut être utile pour désactiver la pré-optimisation des applications susceptibles de recevoir immédiatement les mises à jour de Google Play, car les mises à jour rendraient obsolète le code pré-optimisé dans l'image système. Ceci est également utile pour économiser de l'espace sur les OTA de mise à niveau de version majeure, car les utilisateurs peuvent déjà disposer de versions plus récentes d'applications dans la partition de données.

    LOCAL_DEX_PREOPT prend en charge les valeurs 'true' ou 'false' pour activer ou désactiver la pré-optimisation, respectivement. De plus, "nostripping" peut être spécifié si la pré-optimisation ne doit pas supprimer le fichier classes.dex du fichier APK ou JAR. Normalement, ce fichier est supprimé car il n'est plus nécessaire après la pré-optimisation, mais cette dernière option est nécessaire pour permettre aux signatures APK tierces de rester valides.

  • PRODUCT_DEX_PREOPT_BOOT_FLAGS
  • Passe des options à dex2oat pour contrôler la façon dont l'image de démarrage est compilée. Il peut être utilisé pour spécifier des listes de classes d'images personnalisées, des listes de classes compilées et des filtres de compilateur.

  • PRODUCT_DEX_PREOPT_DEFAULT_FLAGS
  • Passe des options à dex2oat pour contrôler la manière dont tout ce qui n'est pas l'image de démarrage est compilé.

  • PRODUCT_DEX_PREOPT_MODULE_CONFIGS
  • Fournit la possibilité de transmettre les options dex2oat pour une configuration de module et de produit particulière. Il est défini dans le fichier device.mk d'un produit par $(call add-product-dex-preopt-module-config,<modules>,<option>)<modules> est une liste de noms LOCAL_MODULE et LOCAL_PACKAGE pour JAR et APK fichiers, respectivement.

  • PRODUCT_DEXPREOPT_SPEED_APPS (New in Android 8)
  • Liste des applications qui ont été identifiées comme étant au cœur des produits et qu'il est souhaitable de compiler avec le filtre du compilateur speed . Par exemple, les applications persistantes telles que SystemUI ont la possibilité d'utiliser la compilation guidée par profil uniquement au prochain redémarrage, il peut donc être préférable pour le produit que ces applications soient toujours compilées par AOT.

  • PRODUCT_SYSTEM_SERVER_APPS (New in Android 8)
  • Liste des applications chargées par le serveur système. Ces applications sont compilées par défaut avec le filtre du compilateur speed .

  • PRODUCT_ART_TARGET_INCLUDE_DEBUG_BUILD(Post Android 8)
  • S'il faut inclure une version de débogage d'ART sur l'appareil. Par défaut, ceci est activé pour les builds userdebug et eng. Le comportement peut être remplacé en définissant explicitement l'option sur true ou false .

    Par défaut, l'appareil utilise la version non déboguée ( libart.so ). Pour basculer, définissez la propriété système persist.sys.dalvik.vm.lib.2 sur libartd.so .

  • WITH_DEXPREOPT_PIC (Removed in Android 8)
  • Dans Android 5.1.0 à Android 6.0.1, WITH_DEXPREOPT_PIC peut être spécifié pour activer le code indépendant de la position (PIC). Avec cela, le code compilé à partir de l'image n'a pas besoin d'être déplacé de /system vers /data/dalvik-cache, ce qui permet d'économiser de l'espace dans la partition de données. Cependant, il y a un léger impact sur l'exécution car il désactive une optimisation qui tire parti du code dépendant de la position. En règle générale, les périphériques souhaitant économiser de l'espace dans /data doivent activer la compilation PIC.

    Dans Android 7.0, la compilation PIC était activée par défaut.

  • WITH_DEXPREOPT_BOOT_IMG_ONLY (supprimé dans Android 8 MR1)
  • Cette option a été remplacée par WITH_DEXPREOPT_BOOT_IMG_AND_SYSTEM_SERVER_ONLY qui préopte également les jars du serveur système.

  • PRODUCT_SYSTEM_SERVER_COMPILER_FILTER
  • Cette option spécifie le filtre du compilateur pour le serveur système.

    • (depuis Android 14 (AOSP expérimental)) S'il n'est pas spécifié, le filtre du compilateur speed-profile est utilisé, ou le filtre du compilateur de speed est utilisé si aucun profil n'est fourni.
    • (jusqu'à Android 13) S'il n'est pas spécifié, le filtre du compilateur de speed est utilisé.
    • S'il est défini sur speed , le filtre du compilateur de speed est utilisé.
    • S'il est défini sur speed-profile , le filtre de compilateur speed-profile est utilisé, ou le filtre de compilateur de verify est utilisé si aucun profil n'est fourni.
    • S'il est défini sur verify , le filtre du compilateur de verify est utilisé.

  • PRODUCT_SYSTEM_SERVER_JARS , PRODUCT_APEX_SYSTEM_SERVER_JARS , PRODUCT_STANDALONE_SYSTEM_SERVER_JARS , PRODUCT_APEX_STANDALONE_SYSTEM_SERVER_JARS
  • Voici les listes de fichiers JAR chargés par le serveur système. Les jars sont compilés avec le filtre du compilateur spécifié par PRODUCT_SYSTEM_SERVER_COMPILER_FILTER

    • (obligatoire) PRODUCT_SYSTEM_SERVER_JARS : liste des fichiers jar de chemin de classe du serveur système sur la plate-forme (c'est-à-dire dans le cadre de SYSTEMSERVERCLASSPATH ). L'ajout de jars de chemin de classe de serveur système à cette liste est requis. Si vous ne parvenez pas à ajouter des jars de chemin de classe de serveur système à la liste, ces jars ne seront pas chargés.
    • (obligatoire) PRODUCT_APEX_SYSTEM_SERVER_JARS : liste des fichiers jar de chemin de classe du serveur système fournis via apex (c'est-à-dire dans le cadre de SYSTEMSERVERCLASSPATH ). Le format est <apex name>:<jar name> . L'ajout de jars de chemin de classe de serveur système apex à cette liste est requis. Si vous ne parvenez pas à ajouter des fichiers JAR de chemin de classe de serveur système Apex à cette liste, ces fichiers JAR ne seront pas chargés.
    • (facultatif, depuis Android 13) PRODUCT_STANDALONE_SYSTEM_SERVER_JARS : Liste des jars que le serveur système charge dynamiquement à l'aide de classloaders séparés (via SystemServiceManager.startServiceFromJar ). L'ajout de jars de serveur système autonome à cette liste n'est pas obligatoire mais fortement recommandé car cela rend les jars compilés et a donc de bonnes performances d'exécution.
    • (requis, depuis Android 13) PRODUCT_APEX_STANDALONE_SYSTEM_SERVER_JARS : liste des jars fournis via apex que le serveur système charge dynamiquement à l'aide de classloaders séparés (c'est-à-dire via SystemServiceManager.startServiceFromJar ou déclarés comme <apex-system-service> ). Le format est <apex name>:<jar name> . L'ajout de fichiers JAR de serveur de système Apex autonomes à cette liste est requis. Le fait de ne pas ajouter de fichiers JAR de serveur de système Apex autonomes à cette liste entraîne un échec de démarrage.

    Configuration du chemin de classe de démarrage

    • Liste des classes préchargées
    • La liste des classes préchargées est une liste de classes que le zygote initialise au démarrage. Cela évite à chaque application d'avoir à exécuter ces initialiseurs de classe séparément, ce qui leur permet de démarrer plus rapidement et de partager des pages en mémoire. Le fichier de liste des classes préchargées se trouve par défaut dans frameworks/base/config/preloaded-classes et contient une liste adaptée à une utilisation typique du téléphone. Cela peut être différent pour d'autres appareils tels que les appareils portables et doit être réglé en conséquence. Soyez prudent lorsque vous réglez cela; ajouter trop de classes gaspille de la mémoire lorsque les classes inutilisées sont chargées. Ajouter trop peu de classes oblige chaque application à avoir sa propre copie, ce qui, encore une fois, gaspille de la mémoire.

      Exemple d'utilisation (dans le fichier device.mk du produit) :

      PRODUCT_COPY_FILES += <filename>:system/etc/preloaded-classes
      

      Remarque : Cette ligne doit être placée avant d'hériter de tout fichier makefile de configuration de produit qui obtient celui par défaut à partir de : build/target/product/base.mk

    Configuration d'exécution

    Options de jit

    Les options suivantes affectent les versions d'Android uniquement lorsque le compilateur ART JIT est disponible.

    • dalvik.vm.usejit : si le JIT est activé ou non.
    • dalvik.vm.jitinitialsize (64K par défaut) : la capacité initiale du cache de code. Le code cache va régulièrement GC et augmenter si besoin.
    • dalvik.vm.jitmaxsize (64M par défaut) : la capacité maximale du cache de code.
    • dalvik.vm.jitthreshold : (par défaut 10000) - Il s'agit du seuil que le compteur "hotness" d'une méthode doit franchir pour que la méthode soit compilée JIT. Le compteur "hotness" est une métrique interne au runtime. Il comprend le nombre d'appels, les branchements en amont et d'autres facteurs.
    • dalvik.vm.usejitprofiles : si les profils JIT sont activés ou non ; ceci peut être utilisé même si dalvik.vm.usejit est faux. Notez que si cela est faux, le speed-profile du filtre du compilateur ne compile aucune méthode AOT et équivaut à verify .
    • dalvik.vm.jitprithreadweight (valeur par défaut dalvik.vm.jitthreshold / 20) - Le poids des "échantillons" JIT (voir jitthreshold) pour le thread d'interface utilisateur de l'application. Utilisez-le pour accélérer la compilation des méthodes qui affectent directement l'expérience des utilisateurs lors de l'interaction avec l'application.
    • dalvik.vm.jittransitionweight : (par défaut à dalvik.vm.jitthreshold / 10) le poids de l'invocation de la méthode qui fait la transition entre le code compilé et l'interpréteur. Cela permet de s'assurer que les méthodes impliquées sont compilées pour minimiser les transitions (qui sont coûteuses).

    Options du gestionnaire de packages

    Depuis Android 7.0, il existe un moyen générique de spécifier le niveau de compilation/vérification qui s'est produit à différentes étapes. Les niveaux de compilation peuvent être configurés via les propriétés système, les valeurs par défaut étant :

    • pm.dexopt.install=speed-profile
    • Il s'agit du filtre de compilation utilisé lors de l'installation d'applications via Google Play. Nous vous recommandons de définir le filtre d'installation sur speed-profile afin de permettre l'utilisation de profils à partir des fichiers de métadonnées dex. Notez que si un profil n'est pas fourni ou s'il est vide, speed-profile équivaut à vérifier.

    • pm.dexopt.bg-dexopt=speed-profile
    • Il s'agit du filtre de compilation utilisé lorsque l'appareil est inactif, en charge et complètement chargé. Essayez le filtre de compilateur de speed-profile pour tirer parti de la compilation guidée par profil et économiser sur le stockage.

    • pm.dexopt.boot-after-ota=verify
    • Le filtre de compilation utilisé après une mise à jour en direct. Nous recommandons fortement le filtre de verify du compilateur pour cette option afin d'éviter des temps de démarrage très longs.

    • pm.dexopt.first-boot=verify
    • Le filtre de compilation pour la première fois que l'appareil démarre. Le filtre utilisé ici n'affecte que le temps de démarrage après l'usine. Nous vous recommandons de verify le filtre pour éviter de longs délais avant qu'un utilisateur puisse utiliser le téléphone pour la toute première fois. Notez que si toutes les applications de l'image système sont déjà compilées avec verify , speed-profile ou speed avec le bon contexte de chargeur de classe, pm.dexopt.first-boot n'aura aucun effet.

    Options Dex2oat

    Notez que ces options affectent dex2oat lors de la compilation sur l'appareil ainsi que lors de la pré-optimisation, alors que la plupart des options décrites ci-dessus n'affectent que la pré-optimisation.

    Pour contrôler dex2oat pendant la compilation de l'image de démarrage :

    • dalvik.vm.image-dex2oat-Xms : taille initiale du tas
    • dalvik.vm.image-dex2oat-Xmx : taille maximale du segment de mémoire
    • dalvik.vm.image-dex2oat-filter : option de filtre du compilateur
    • dalvik.vm.image-dex2oat-threads : nombre de threads à utiliser

    Pour contrôler dex2oat pendant qu'il compile tout sauf l'image de démarrage :

    • dalvik.vm.dex2oat-Xms : taille initiale du tas
    • dalvik.vm.dex2oat-Xmx : taille maximale du segment de mémoire
    • dalvik.vm.dex2oat-filter : option de filtre du compilateur

    Sur les versions jusqu'à Android 6.0, une option supplémentaire est fournie pour tout compiler en plus de l'image de démarrage :

    • dalvik.vm.dex2oat-threads : nombre de threads à utiliser

    À partir d'Android 6.1, cela devient deux options supplémentaires pour tout compiler en plus de l'image de démarrage :

    • dalvik.vm.boot-dex2oat-threads : nombre de threads à utiliser au démarrage
    • dalvik.vm.dex2oat-threads : nombre de threads à utiliser après le démarrage

    À partir d'Android 7.1, deux options sont fournies pour contrôler l'utilisation de la mémoire lors de la compilation de tout en dehors de l'image de démarrage :

    • dalvik.vm.dex2oat-very-large : taille minimale totale du fichier dex en octets pour désactiver la compilation AOT
    • dalvik.vm.dex2oat-swap : utilisez le fichier d'échange dex2oat (pour les appareils à faible mémoire)

    Les options qui contrôlent la taille de tas initiale et maximale pour dex2oat ne doivent pas être réduites car elles pourraient limiter les applications pouvant être compilées.

    À partir d'Android 11, trois options d'affinité CPU sont fournies pour permettre aux threads du compilateur d'être limités à un groupe spécifique de CPU :

    • dalvik.vm.boot-dex2oat-cpu-set : processeurs exécutant des threads dex2oat au démarrage
    • dalvik.vm.image-dex2oat-cpu-set : processeurs exécutant dex2oat lors de la compilation de l'image de démarrage
    • dalvik.vm.dex2oat-cpu-set : processeurs exécutant des threads dex2oat après le démarrage

    Les processeurs doivent être spécifiés sous la forme d'une liste d'ID de processeur séparés par des virgules. Par exemple, pour exécuter sur dex2oat sur les CPU 0-3, définissez :

    dalvik.vm.dex2oat-cpu-set=0,1,2,3
    

    Lors de la définition des propriétés d'affinité du processeur, nous vous recommandons de faire correspondre la propriété correspondante pour que le nombre de threads dex2oat corresponde au nombre de processeurs sélectionnés afin d'éviter les conflits de mémoire et d'E/S inutiles :

    dalvik.vm.dex2oat-cpu-set=0,1,2,3
    dalvik.vm.dex2oat-threads=4
    

    À partir d'Android 12, les options suivantes ont été ajoutées :

    • dalvik.vm.ps-min-first-save-ms : le temps d'attente pour que le runtime génère un profil de l'application, la première fois que l'application est lancée
    • dalvik.vm.ps-min-save-period-ms : le temps minimum à attendre avant de mettre à jour le profil d'une app
    • dalvik.vm.systemservercompilerfilter : le filtre du compilateur que l'appareil utilise lors de la recompilation du serveur système

    Configuration spécifique A/B

    Configuration de la ROM

    À partir d'Android 7.0, les appareils peuvent utiliser deux partitions système pour activer les mises à jour système A/B . Pour économiser sur la taille de la partition système, les fichiers préoptés peuvent être installés dans la deuxième partition système inutilisée. Ils sont ensuite copiés sur la partition de données au premier démarrage.

    Exemple d'utilisation (dans device-common.mk ):

    PRODUCT_PACKAGES += \
         cppreopts.sh
    PRODUCT_PROPERTY_OVERRIDES += \
         ro.cp_system_other_odex=1
    

    Et dans BoardConfig.mk de l'appareil :

    BOARD_USES_SYSTEM_OTHER_ODEX := true
    

    Notez que le code du chemin d'accès aux classes de démarrage, le code du serveur système et les applications principales spécifiques au produit sont toujours compilés sur la partition système. Par défaut, toutes les autres applications sont compilées sur la deuxième partition système inutilisée. Cela peut être contrôlé avec le SYSTEM_OTHER_ODEX_FILTER , qui a une valeur par défaut de :

    SYSTEM_OTHER_ODEX_FILTER ?= app/% priv-app/%
    

    Arrière-plan dexopt OTA

    Avec les appareils compatibles A/B, les applications peuvent être compilées en arrière-plan pour la mise à jour vers la nouvelle image système. Voir Compilation d'applications en arrière-plan pour inclure éventuellement le script de compilation et les fichiers binaires dans l'image système. Le filtre de compilation utilisé pour cette compilation est contrôlé avec :

    pm.dexopt.ab-ota=speed-profile
    

    Nous vous recommandons d'utiliser speed-profile pour tirer parti de la compilation guidée par profil et économiser sur le stockage.