Implementar el compilador ART justo a tiempo

El tiempo de ejecución de Android (ART) incluye un compilador justo a tiempo (JIT) con creación de perfiles de código que mejora continuamente el rendimiento de las aplicaciones de Android a medida que se ejecutan. El compilador JIT complementa el compilador adelantado (AOT) actual de ART y mejora el rendimiento en tiempo de ejecución, ahorra espacio de almacenamiento y acelera las actualizaciones de aplicaciones y sistemas. También mejora el compilador AOT al evitar la desaceleración del sistema durante las actualizaciones automáticas de aplicaciones o la recompilación de aplicaciones durante las actualizaciones inalámbricas (OTA).

Aunque JIT y AOT utilizan el mismo compilador con un conjunto similar de optimizaciones, es posible que el código generado no sea idéntico. JIT hace uso de información de tipo de tiempo de ejecución, puede realizar una mejor integración y hace posible la compilación de reemplazo de pila (OSR), todo lo cual genera un código ligeramente diferente.

arquitectura JIT

arquitectura JIT
Figura 1. Arquitectura JIT.

Compilación JIT

La compilación JIT implica las siguientes actividades:

Compilación guiada por perfil
Figura 2. Compilación guiada por perfiles.
  1. El usuario ejecuta la aplicación, que luego activa ART para cargar el archivo .dex .
    • Si el archivo .oat (el binario AOT para el archivo .dex ) está disponible, ART lo usa directamente. Aunque los archivos .oat se generan con regularidad, no siempre contienen código compilado (binario AOT).
    • Si el archivo .oat no contiene código compilado, ART se ejecuta a través de JIT y el intérprete para ejecutar el archivo .dex .
  2. JIT está habilitado para cualquier aplicación que no esté compilada de acuerdo con el filtro de compilación speed (que dice "compila tanto como puedas desde la aplicación").
  3. Los datos del perfil JIT se vuelcan en un archivo en un directorio del sistema al que solo puede acceder la aplicación.
  4. El demonio de compilación AOT ( dex2oat ) analiza ese archivo para impulsar su compilación.

    demonio JIT
    Figura 3. Actividades del demonio JIT.

El servicio Google Play es un ejemplo utilizado por otras aplicaciones que se comportan de manera similar a las bibliotecas compartidas.

flujo de trabajo JIT

arquitectura JIT
Figura 4. Flujo de datos JIT.
  • La información de creación de perfiles se almacena en la caché de código y se somete a recolección de basura bajo presión de memoria.
    • No hay garantía de que una instantánea tomada cuando la aplicación estaba en segundo plano contendrá datos completos (es decir, todo lo que fue JITed).
    • No se intenta garantizar que todo se registre (ya que esto puede afectar el rendimiento del tiempo de ejecución).
  • Los métodos pueden estar en tres estados diferentes:
    • interpretado (código dex)
    • JIT compilado
    • AOT compilado
    Si existe código JIT y AOT (por ejemplo, debido a repetidas desoptimizaciones), se prefiere el código JIT.
  • El requisito de memoria para ejecutar JIT sin afectar el rendimiento de la aplicación en primer plano depende de la aplicación en cuestión. Las aplicaciones grandes requieren más memoria que las pequeñas. En general, las aplicaciones grandes se estabilizan en torno a los 4 MB.

Activar el registro JIT

Para activar el registro JIT, ejecute los siguientes comandos:

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

Deshabilitar JIT

Para deshabilitar JIT, ejecute los siguientes comandos:

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

Compilación de fuerza

Para forzar la compilación, ejecute lo siguiente:

adb shell cmd package compile

Casos de uso comunes para forzar la compilación de un paquete específico:

  • Basado en perfil:
    adb shell cmd package compile -m speed-profile -f my-package
    
  • Completo:
    adb shell cmd package compile -m speed -f my-package
    

Casos de uso comunes para forzar la compilación de todos los paquetes:

  • Basado en perfil:
    adb shell cmd package compile -m speed-profile -f -a
    
  • Completo:
    adb shell cmd package compile -m speed -f -a
    

Borrar datos de perfil

En Android 13 o anterior

Para borrar los datos del perfil local y eliminar el código compilado, ejecute lo siguiente:

adb shell pm compile --reset 

En Android 14 o posterior

Para borrar solo los datos del perfil local:

adb shell pm art clear-app-profiles 

Nota: A diferencia del comando para Android 13 o versiones anteriores, este comando no borra los datos del perfil externo (`.dm`) que están instalados con la aplicación.

Para borrar los datos del perfil local y eliminar el código compilado generado a partir de los datos del perfil local (es decir, restablecer el estado de instalación), ejecute lo siguiente:

adb shell pm compile --reset 

Nota: Este comando no elimina el código compilado generado a partir de datos de perfil externos (`.dm`) que se instala con la aplicación.

Para borrar todo el código compilado, ejecute este comando:

adb shell cmd package compile -m verify -f 

Nota: Este comando conserva los datos del perfil local.