Google se compromete a impulsar la igualdad racial para las comunidades afrodescendientes. Obtén información al respecto.

Configuración de ART

Esta página explica cómo configurar ART y sus opciones de compilación. Los temas tratados aquí incluyen la configuración de la precompilación de la imagen del sistema, las opciones de compilación de dex2oat y cómo compensar el espacio de partición del sistema, el espacio de partición de datos y el rendimiento.

Consulte ART y Dalvik , el formato ejecutable de Dalvik y las páginas restantes en source.android.com para trabajar con ART. Consulte Verificación del comportamiento de la aplicación en Android Runtime (ART) para asegurarse de que sus aplicaciones funcionen correctamente.

Cómo funciona el ART

ART usa compilación anticipada (AOT) y, a partir de Android 7.0 (Nougat o N), usa una combinación híbrida de AOT, compilación justo a tiempo (JIT) y compilación guiada por perfil. La combinación de todos estos modos de compilación es configurable y se discutirá en esta sección. Como ejemplo, los dispositivos Pixel se configuran con el siguiente flujo de compilación:

  1. Una aplicación se instala inicialmente sin ninguna compilación AOT. Las primeras veces que se ejecuta la aplicación, se interpreta y los métodos que se ejecutan con frecuencia se compilan JIT.
  2. Cuando el dispositivo está inactivo y cargándose, un demonio de compilación se ejecuta para compilar AOT el código de uso frecuente en función de un perfil generado durante las primeras ejecuciones.
  3. El siguiente reinicio de una aplicación utiliza el código guiado por perfil y evita realizar la compilación JIT en tiempo de ejecución para los métodos ya compilados. Los métodos que se compilan con JIT durante las nuevas ejecuciones se agregan al perfil, que luego será recogido por el demonio de compilación.

ART comprende un compilador (la herramienta dex2oat ) y un tiempo de ejecución ( libart.so ) que se carga para iniciar Zygote. La herramienta dex2oat toma un archivo APK y genera uno o más archivos de artefactos de compilación que carga el tiempo de ejecución. La cantidad de archivos, sus extensiones y nombres están sujetos a cambios entre las versiones, pero a partir de la versión de Android 8, los archivos que se generan son:

  • .vdex : contiene el código DEX sin comprimir del APK, con algunos metadatos adicionales para acelerar la verificación.
  • .odex : contiene código compilado AOT para métodos en el APK.
  • .art (optional) : contiene representaciones internas ART de algunas cadenas y clases enumeradas en el APK, que se utilizan para acelerar el inicio de la aplicación.

Opciones de compilación

Las opciones de compilación para ART son de dos categorías:

  1. Configuración de la ROM del sistema: qué código se compila AOT al crear una imagen del sistema.
  2. Configuración de tiempo de ejecución: cómo ART compila y ejecuta aplicaciones en un dispositivo.

Una opción básica de ART para configurar estas dos categorías son los filtros del compilador . Los filtros del compilador controlan cómo ART compila el código DEX y es una opción que se pasa a la herramienta dex2oat . A partir de Android 8, hay cuatro filtros admitidos oficialmente:

  • verify : solo ejecuta la verificación del código DEX.
  • quicken : (eliminado desde Android 12) ejecuta la verificación del código DEX y optimiza algunas instrucciones DEX para obtener un mejor rendimiento del intérprete.
  • speed : ejecute la verificación del código DEX y AOT-compile todos los métodos.
  • speed-profile : ejecuta la verificación del código DEX y los métodos de compilación AOT enumerados en un archivo de perfil.

Configuración de la ROM del sistema

Hay una serie de opciones de creación de ART disponibles para configurar una ROM del sistema. La forma en que configura estas opciones depende del espacio de almacenamiento disponible para la imagen del sistema y la cantidad de aplicaciones preinstaladas. Los JAR/APK que se compilan en una ROM del sistema se pueden dividir en cuatro categorías:

  • Código de classpath de arranque: compilado con el filtro del compilador speed-profile de forma predeterminada.
  • Código del servidor del sistema (consulte PRODUCT_SYSTEM_SERVER_JARS , PRODUCT_APEX_SYSTEM_SERVER_JARS , PRODUCT_STANDALONE_SYSTEM_SERVER_JARS , PRODUCT_APEX_STANDALONE_SYSTEM_SERVER_JARS más adelante en este documento):
    • (desde Android 14 (AOSP experimental)) compilado con el filtro del compilador speed-profile de forma predeterminada, o compilado con el filtro del compilador de speed si no se proporciona un perfil.
    • (hasta Android 13) compilado con el filtro del compilador de speed de forma predeterminada.
    Configurable a través de PRODUCT_SYSTEM_SERVER_COMPILER_FILTER (ver más adelante en este documento).
  • Aplicaciones principales específicas del producto (consulte PRODUCT_DEXPREOPT_SPEED_APPS más adelante en este documento): compiladas con el filtro del compilador de speed de forma predeterminada.
  • Todas las demás aplicaciones: compiladas con el filtro del compilador speed-profile de forma predeterminada o compiladas con el filtro del compilador de verify si no se proporciona un perfil.

    Configurable a través de PRODUCT_DEX_PREOPT_DEFAULT_COMPILER_FILTER (ver más adelante en este documento).

Opciones de archivo MAKE

  • WITH_DEXPREOPT
  • Si se invoca dex2oat en el código DEX instalado en la imagen del sistema. Habilitado por defecto.

  • DONT_DEXPREOPT_PREBUILTS (desde Android 5)
  • Habilitar DONT_DEXPREOPT_PREBUILTS evita que las compilaciones previas se optimicen previamente. Estas son aplicaciones que include $(BUILD_PREBUILT) especificado en su Android.mk . Omitir la optimización previa de las aplicaciones prediseñadas que probablemente se actualicen a través de Google Play ahorra espacio en la imagen del sistema, pero aumenta el tiempo de primer arranque. Tenga en cuenta que esta opción no tiene efecto en las aplicaciones prediseñadas definidas en Android.bp .

  • PRODUCT_DEX_PREOPT_DEFAULT_COMPILER_FILTER (desde Android 9)
  • PRODUCT_DEX_PREOPT_DEFAULT_COMPILER_FILTER especifica el filtro de compilador predeterminado para aplicaciones optimizadas previamente. Estas aplicaciones están definidas en Android.bp o include $(BUILD_PREBUILT) especificado en su Android.mk . Si no se especifica, el valor predeterminado es speed-profile o verify si el valor no se especifica y no se proporciona un perfil.

  • WITH_DEXPREOPT_BOOT_IMG_AND_SYSTEM_SERVER_ONLY (nuevo en Android 8 MR1)
  • Habilitar WITH_DEXPREOPT_BOOT_IMG_AND_SYSTEM_SERVER_ONLY optimiza previamente solo el classpath de arranque y los archivos jar del servidor del sistema.

  • LOCAL_DEX_PREOPT
  • La optimización previa también se puede habilitar o deshabilitar en una aplicación individual especificando la opción LOCAL_DEX_PREOPT en la definición del módulo. Esto puede ser útil para deshabilitar la optimización previa de aplicaciones que pueden recibir actualizaciones de Google Play de inmediato, ya que las actualizaciones dejarían obsoleto el código optimizado previamente en la imagen del sistema. Esto también es útil para ahorrar espacio en las OTA de actualización de versiones principales, ya que es posible que los usuarios ya tengan versiones más nuevas de aplicaciones en la partición de datos.

    LOCAL_DEX_PREOPT admite los valores "verdadero" o "falso" para habilitar o deshabilitar la optimización previa, respectivamente. Además, se puede especificar 'nostripping' si la optimización previa no debe eliminar el archivo classes.dex del archivo APK o JAR. Normalmente, este archivo se elimina porque ya no es necesario después de la optimización previa, pero esta última opción es necesaria para permitir que las firmas de APK de terceros sigan siendo válidas.

  • PRODUCT_DEX_PREOPT_BOOT_FLAGS
  • Pasa opciones a dex2oat para controlar cómo se compila la imagen de arranque. Se puede usar para especificar listas de clases de imágenes personalizadas, listas de clases compiladas y filtros de compilador.

  • PRODUCT_DEX_PREOPT_DEFAULT_FLAGS
  • Pasa opciones a dex2oat para controlar cómo se compila todo, además de la imagen de arranque.

  • PRODUCT_DEX_PREOPT_MODULE_CONFIGS
  • Brinda la capacidad de pasar opciones de dex2oat para un módulo y una configuración de producto en particular. Se establece en el archivo device.mk de un producto mediante $(call add-product-dex-preopt-module-config,<modules>,<option>) donde <modules> es una lista de nombres LOCAL_MODULE y LOCAL_PACKAGE para JAR y APK archivos, respectivamente.

  • PRODUCT_DEXPREOPT_SPEED_APPS (New in Android 8)
  • Lista de aplicaciones que se han identificado como fundamentales para los productos y que es deseable compilar con el filtro del compilador de speed . Por ejemplo, las aplicaciones persistentes como SystemUI tienen la oportunidad de usar la compilación guiada por perfil solo en el próximo reinicio, por lo que puede ser mejor para el producto tener estas aplicaciones siempre compiladas con AOT.

  • PRODUCT_SYSTEM_SERVER_APPS (New in Android 8)
  • Lista de aplicaciones que carga el servidor del sistema. Estas aplicaciones se compilan de forma predeterminada con el filtro del compilador de speed .

  • PRODUCT_ART_TARGET_INCLUDE_DEBUG_BUILD(Post Android 8)
  • Si incluir una versión de depuración de ART en el dispositivo. De forma predeterminada, esto está habilitado para compilaciones de depuración de usuarios y eng. El comportamiento se puede anular estableciendo explícitamente la opción en true o false .

    De forma predeterminada, el dispositivo utiliza la versión sin depuración ( libart.so ). Para cambiar, establezca la propiedad del sistema persist.sys.dalvik.vm.lib.2 en libartd.so .

  • WITH_DEXPREOPT_PIC (Removed in Android 8)
  • En Android 5.1.0 a Android 6.0.1, se puede especificar WITH_DEXPREOPT_PIC para habilitar el código independiente de la posición (PIC). Con esto, el código compilado de la imagen no tiene que ser reubicado de /system a /data/dalvik-cache, ahorrando espacio en la partición de datos. Sin embargo, hay un ligero impacto en el tiempo de ejecución porque deshabilita una optimización que aprovecha el código dependiente de la posición. Por lo general, los dispositivos que desean ahorrar espacio en /data deben habilitar la compilación de PIC.

    En Android 7.0, la compilación de PIC estaba habilitada de forma predeterminada.

  • WITH_DEXPREOPT_BOOT_IMG_ONLY (eliminado en Android 8 MR1)
  • Esta opción se reemplazó con WITH_DEXPREOPT_BOOT_IMG_AND_SYSTEM_SERVER_ONLY que también preopta los archivos jar del servidor del sistema.

  • PRODUCT_SYSTEM_SERVER_COMPILER_FILTER
  • Esta opción especifica el filtro del compilador para el servidor del sistema.

    • (desde Android 14 (AOSP experimental)) Si no se especifica, se usa el filtro del compilador speed-profile , o se usa el filtro del compilador speed si no se proporciona un perfil.
    • (hasta Android 13) Si no se especifica, se usa el filtro del compilador speed .
    • Si se establece en speed , se usa el filtro del compilador de speed .
    • Si se establece en speed-profile , se usa el filtro del compilador speed-profile o se usa el filtro del compilador de verify si no se proporciona un perfil.
    • Si se configura para verify , se usa el filtro del compilador de verify .

  • PRODUCT_SYSTEM_SERVER_JARS , PRODUCT_APEX_SYSTEM_SERVER_JARS , PRODUCT_STANDALONE_SYSTEM_SERVER_JARS , PRODUCT_APEX_STANDALONE_SYSTEM_SERVER_JARS
  • Las siguientes son listas de archivos jar cargados por el servidor del sistema. Los archivos jar se compilan con el filtro del compilador especificado por PRODUCT_SYSTEM_SERVER_COMPILER_FILTER

    • (obligatorio) PRODUCT_SYSTEM_SERVER_JARS : lista de archivos jar de classpath del servidor del sistema en la plataforma (es decir, como parte de SYSTEMSERVERCLASSPATH ). Es necesario agregar archivos jar de classpath del servidor del sistema a esta lista. Si no se pueden agregar archivos jar de classpath del servidor del sistema a la lista, esos archivos jar no se cargarán.
    • (obligatorio) PRODUCT_APEX_SYSTEM_SERVER_JARS : lista de archivos jar de classpath del servidor del sistema entregados a través de Apex (es decir, como parte de SYSTEMSERVERCLASSPATH ). El formato es <apex name>:<jar name> . Es necesario agregar archivos jar de classpath del servidor del sistema apex a esta lista. Si no se agregan los archivos jar classpath del servidor del sistema apex a esta lista, esos archivos jar no se cargarán.
    • (opcional, desde Android 13) PRODUCT_STANDALONE_SYSTEM_SERVER_JARS : Lista de archivos jar que el servidor del sistema carga dinámicamente usando cargadores de clases separados (a través de SystemServiceManager.startServiceFromJar ). No es necesario agregar archivos jar de servidores de sistema independientes a esta lista, pero se recomienda encarecidamente porque hace que los archivos jar se compilen y, por lo tanto, tengan un buen rendimiento de tiempo de ejecución.
    • (obligatorio, desde Android 13) PRODUCT_APEX_STANDALONE_SYSTEM_SERVER_JARS : Lista de archivos jar entregados a través de ápex que el servidor del sistema carga dinámicamente usando cargadores de clases separados (es decir, a través de SystemServiceManager.startServiceFromJar o declarado como <apex-system-service> ). El formato es <apex name>:<jar name> . Es necesario agregar archivos jar de servidor de sistema apex independientes a esta lista. Si no se agregan archivos jar independientes del servidor del sistema Apex a esta lista, se produce un error de arranque.

    Configuración de classpath de arranque

    • Lista de clases precargadas
    • La lista de clases precargadas es una lista de clases que el cigoto inicializa al iniciarse. Esto evita que cada aplicación tenga que ejecutar estos inicializadores de clase por separado, lo que les permite iniciarse más rápido y compartir páginas en la memoria. El archivo de la lista de clases precargadas se encuentra en frameworks/base/config/preloaded-classes de forma predeterminada y contiene una lista que está ajustada para el uso típico del teléfono. Esto puede ser diferente para otros dispositivos, como dispositivos portátiles, y debe ajustarse en consecuencia. Tenga cuidado al afinar esto; agregar demasiadas clases desperdicia memoria cuando se cargan clases no utilizadas. Agregar muy pocas clases obliga a cada aplicación a tener su propia copia, lo que de nuevo desperdicia memoria.

      Ejemplo de uso (en el dispositivo del producto.mk):

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

      Nota: Esta línea debe colocarse antes de heredar cualquier archivo MAKE de configuración del producto que obtenga el predeterminado de: build/target/product/base.mk

    Configuración del tiempo de ejecución

    Opciones de Jit

    Las siguientes opciones afectan a las versiones de Android solo donde está disponible el compilador ART JIT.

    • dalvik.vm.usejit: si el JIT está habilitado o no.
    • dalvik.vm.jitinitialsize (predeterminado 64K): la capacidad inicial del caché de código. El caché de código se analizará regularmente y aumentará si es necesario.
    • dalvik.vm.jitmaxsize (predeterminado 64M): la capacidad máxima del caché de código.
    • dalvik.vm.jitthreshold: (predeterminado 10000): este es el umbral que el contador de "calor" de un método debe pasar para que el método se compile JIT. El contador de "calor" es una métrica interna del tiempo de ejecución. Incluye el número de llamadas, bifurcaciones hacia atrás y otros factores.
    • dalvik.vm.usejitprofiles: si los perfiles JIT están habilitados o no; esto se puede usar incluso si dalvik.vm.usejit es falso. Tenga en cuenta que si esto es falso, el speed-profile filtro del compilador no compila AOT ningún método y es equivalente a verify .
    • dalvik.vm.jitprithreadweight (predeterminado en dalvik.vm.jitthreshold / 20): el peso de las "muestras" JIT (consulte jitthreshold) para el subproceso de la interfaz de usuario de la aplicación. Úselo para acelerar la compilación de métodos que afectan directamente la experiencia de los usuarios cuando interactúan con la aplicación.
    • dalvik.vm.jittransitionweight: (predeterminado en dalvik.vm.jitthreshold / 10) el peso de la invocación del método que realiza la transición entre el código de compilación y el intérprete. Esto ayuda a garantizar que los métodos involucrados se compilen para minimizar las transiciones (que son costosas).

    Opciones del administrador de paquetes

    Desde Android 7.0, existe una forma genérica de especificar el nivel de compilación/verificación que ocurrió en varias etapas. Los niveles de compilación se pueden configurar a través de las propiedades del sistema con los valores predeterminados:

    • pm.dexopt.install=speed-profile
    • Este es el filtro de compilación utilizado al instalar aplicaciones a través de Google Play. Recomendamos que el filtro de instalación se establezca en perfil de velocidad para habilitar el uso de perfiles de los archivos de metadatos dex. Tenga en cuenta que si no se proporciona un perfil o si está vacío, el perfil de velocidad es equivalente a verificar.

    • pm.dexopt.bg-dexopt=speed-profile
    • Este es el filtro de compilación que se usa cuando el dispositivo está inactivo, cargándose y completamente cargado. Pruebe el filtro del compilador speed-profile para aprovechar la compilación guiada por perfil y ahorrar en almacenamiento.

    • pm.dexopt.boot-after-ota=verify
    • El filtro de compilación utilizado después de una actualización inalámbrica. Recomendamos encarecidamente el filtro del compilador de verify para esta opción para evitar tiempos de arranque muy largos.

    • pm.dexopt.first-boot=verify
    • El filtro de compilación por primera vez que arranca el dispositivo. El filtro utilizado aquí solo afecta el tiempo de arranque después de la fábrica. Recomendamos verify el filtro para evitar mucho tiempo antes de que un usuario use el teléfono por primera vez. Tenga en cuenta que si todas las aplicaciones en la imagen del sistema ya están compiladas con verify , speed-profile de velocidad o speed con el contexto correcto del cargador de clases, pm.dexopt.first-boot no tendrá ningún efecto.

    Opciones de Dex2oat

    Tenga en cuenta que estas opciones afectan a dex2oat durante la compilación en el dispositivo, así como durante la optimización previa, mientras que la mayoría de las opciones discutidas anteriormente afectan solo a la optimización previa.

    Para controlar dex2oat mientras compila la imagen de arranque:

    • dalvik.vm.image-dex2oat-Xms: tamaño de almacenamiento dinámico inicial
    • dalvik.vm.image-dex2oat-Xmx: tamaño máximo de almacenamiento dinámico
    • dalvik.vm.image-dex2oat-filter: opción de filtro del compilador
    • dalvik.vm.image-dex2oat-threads: número de subprocesos a utilizar

    Para controlar dex2oat mientras compila todo además de la imagen de arranque:

    • dalvik.vm.dex2oat-Xms: tamaño de almacenamiento dinámico inicial
    • dalvik.vm.dex2oat-Xmx: tamaño máximo de almacenamiento dinámico
    • dalvik.vm.dex2oat-filter: opción de filtro del compilador

    En los lanzamientos hasta Android 6.0, se proporciona una opción adicional para compilar todo además de la imagen de arranque:

    • dalvik.vm.dex2oat-threads: número de subprocesos a utilizar

    A partir de Android 6.1, esto se convierte en dos opciones adicionales para compilar todo además de la imagen de arranque:

    • dalvik.vm.boot-dex2oat-threads: número de subprocesos a usar durante el tiempo de arranque
    • dalvik.vm.dex2oat-threads: número de subprocesos para usar después del tiempo de arranque

    A partir de Android 7.1, se proporcionan dos opciones para controlar cómo se usa la memoria al compilar todo, además de la imagen de arranque:

    • dalvik.vm.dex2oat-very-large: tamaño mínimo total del archivo dex en bytes para deshabilitar la compilación AOT
    • dalvik.vm.dex2oat-swap: use el archivo de intercambio dex2oat (para dispositivos con poca memoria)

    Las opciones que controlan el tamaño de almacenamiento dinámico inicial y máximo para dex2oat no deben reducirse, ya que podrían limitar las aplicaciones que se pueden compilar.

    A partir de Android 11, se proporcionan tres opciones de afinidad de CPU para permitir que los subprocesos del compilador se restrinjan a un grupo específico de CPU:

    • dalvik.vm.boot-dex2oat-cpu-set: CPU que ejecutan subprocesos dex2oat durante el arranque
    • dalvik.vm.image-dex2oat-cpu-set: CPU que ejecutan dex2oat mientras compilan la imagen de arranque
    • dalvik.vm.dex2oat-cpu-set: CPU que ejecutan subprocesos dex2oat después del tiempo de arranque

    Las CPU deben especificarse como una lista separada por comas de ID de CPU. Por ejemplo, para ejecutar dex2oat en las CPU 0-3, configure:

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

    Al configurar las propiedades de afinidad de la CPU, recomendamos hacer coincidir la propiedad correspondiente para la cantidad de subprocesos dex2oat para que coincida con la cantidad de CPU seleccionadas para evitar memoria innecesaria y contención de E/S:

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

    A partir de Android 12, se agregaron las siguientes opciones:

    • dalvik.vm.ps-min-first-save-ms: el tiempo de espera para que el tiempo de ejecución genere un perfil de la aplicación, la primera vez que se inicia la aplicación
    • dalvik.vm.ps-min-save-period-ms: el tiempo mínimo de espera antes de actualizar el perfil de una aplicación
    • dalvik.vm.systemservercompilerfilter: el filtro del compilador que utiliza el dispositivo al recompilar el servidor del sistema

    Configuración específica A/B

    configuración de la ROM

    A partir de Android 7.0, los dispositivos pueden usar dos particiones del sistema para habilitar las actualizaciones del sistema A/B . Para ahorrar en el tamaño de la partición del sistema, los archivos preoptados se pueden instalar en la segunda partición del sistema no utilizada. Luego se copian en la partición de datos en el primer arranque.

    Ejemplo de uso (en device-common.mk ):

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

    Y en BoardConfig.mk del dispositivo:

    BOARD_USES_SYSTEM_OTHER_ODEX := true
    

    Tenga en cuenta que el código de classpath de arranque, el código del servidor del sistema y las aplicaciones principales específicas del producto siempre se compilan en la partición del sistema. De forma predeterminada, todas las demás aplicaciones se compilan en la segunda partición del sistema no utilizada. Esto se puede controlar con SYSTEM_OTHER_ODEX_FILTER , que tiene un valor predeterminado de:

    SYSTEM_OTHER_ODEX_FILTER ?= app/% priv-app/%
    

    Fondo dexopt OTA

    Con dispositivos habilitados para A/B, las aplicaciones se pueden compilar en segundo plano para actualizarlas a la nueva imagen del sistema. Consulte Compilación de la aplicación en segundo plano para incluir opcionalmente el script de compilación y los archivos binarios en la imagen del sistema. El filtro de compilación utilizado para esta compilación se controla con:

    pm.dexopt.ab-ota=speed-profile
    

    Recomendamos usar speed-profile para aprovechar la compilación guiada por perfiles y ahorrar en almacenamiento.