AOT — qué es la compilación Ahead-Of-Time y cómo funciona

Autor: IT Sectr Publicado: 2026-04-16 Tiempo de lectura: 9 min

AOT (Ahead-Of-Time) — una tecnología de compilación en la que el código fuente o el bytecode se convierte en instrucciones de máquina antes de ejecutar el programa, en la fase de compilación o instalación. En Android, la compilación AOT se convirtió en una innovación clave del entorno de ejecución ART, que reemplazó a Dalvik en la versión 5.0 Lollipop. Según Google, 2024, la compilación AOT en ART elimina los retrasos de calentamiento y reduce el consumo de energía de las aplicaciones en un 10–15% en comparación con el enfoque JIT.

Puntos clave

  • AOT — compilación Ahead-Of-Time: conversión de código a código machine antes de la ejecución del programa.
  • En Android, AOT se realiza mediante la utilidad dex2oat durante la instalación del APK o en segundo plano.
  • La principal ventaja de AOT es el inicio instantáneo de aplicaciones sin fase de calentamiento.
  • La desventaja es el mayor tiempo de instalación y el espacio en disco adicional del 15–30%.
  • Los sistemas modernos utilizan un enfoque híbrido: JIT para los primeros inicios, AOT para métodos hot.

¿Qué es la compilación AOT?

Ahead-Of-Time (AOT) es un método de compilación en el que un programa se convierte en código machine antes de ejecutarse. El término “Ahead-Of-Time” contrasta con JIT (Just-In-Time): si JIT compila “justo a tiempo,” entonces AOT compila “por adelantado.” Un compilador AOT toma como entrada el código fuente o una representación intermedia (bytecode) y genera un archivo ejecutable listo para usar.

La historia de AOT se remonta a los compiladores tradicionales de C y C++, donde la compilación siempre ocurre antes de la ejecución. En el contexto de los lenguajes administrados (Java, C#, Dart), AOT es una innovación más reciente: durante mucho tiempo se creyó que las capacidades dinámicas (reflexión, carga dinámica de clases) dificultaban la implementación de AOT. Google resolvió este problema para Android creando dex2oat, un compilador AOT de bytecode DEX a código nativo.

Cómo funciona AOT

Un compilador AOT realiza un ciclo completo de traducción. La primera etapa es el análisis sintáctico y la construcción de un árbol de sintaxis abstracta (AST). La segunda es el análisis y la optimización: eliminación de código muerto, inline, optimización de bucles. La tercera es la generación de código machine para la arquitectura objetivo (ARM, ARM64, x86). El resultado es un archivo ejecutable que no requiere procesamiento adicional en tiempo de ejecución.

bash
# Ejecución manual del compilador AOT dex2oat
dex2oat --dex-file=classes.dex \
        --oat-file=classes.oat \
        --arch=arm64 \
        --instruction-set-variant=generic

# Verificar el archivo OAT compilado
oatdump --oat-file=classes.oat --output=oat_dump.txt

AOT en Android: dex2oat y archivos OAT

En Android, la compilación AOT se implementa mediante la utilidad dex2oat (dalvik executable to optimized android translator). Cuando un usuario instala una aplicación, el sistema ejecuta dex2oat, que lee los archivos DEX del APK, optimiza el bytecode y crea un archivo OAT, un binario ELF con código nativo. Este archivo se guarda en la partición /data/dalvik-cache/.

El proceso de compilación incluye varios niveles de optimización. El nivel básico — verificación de bytecode y optimizaciones básicas (eliminación de código muerto, plegado de constantes). El nivel intermedio — inline de métodos, desenrollado de bucles, análisis de escape. El nivel máximo — optimizaciones globales de toda la aplicación, incluyendo devirtualización y optimización del tamaño de pila. El nivel de optimización depende del modo de compilación (speed, speed-profile, space).

Estructura del archivo OAT

Un archivo OAT utiliza el formato ELF (Executable and Linkable Format), el mismo formato que usan los binarios nativos de Linux. Dentro del archivo OAT se encuentra el código compilado para cada método de la aplicación, junto con metadatos: información sobre clases, campos, métodos y sus relaciones. ART utiliza estos metadatos para la carga rápida de clases y la resolución de referencias simbólicas sin análisis completo de DEX.

Componente OATPropósito
Cabecera ELFCabecera del formato ELF
Sección de códigoCódigo machine de métodos compilados
Cabecera OATMetadatos de ART: versión, tamaños de sección
Secciones DEXDatos DEX originales para reflexión
Tabla de enlaceTabla de enlace para JNI y bibliotecas nativas

AOT vs JIT: análisis comparativo

AOT y JIT representan diferentes puntos en el espacio de compromiso entre rendimiento y flexibilidad. AOT proporciona la máxima velocidad de ejecución desde el primer segundo, pero requiere más espacio en disco y tiempo de instalación. JIT ahorra espacio y tiempo de instalación, pero paga con retrasos de calentamiento y picos de consumo de energía.

El factor clave de selección es el caso de uso. Para aplicaciones que se inician una vez y funcionan durante mucho tiempo (juegos, editores, navegación), AOT es preferible: los costos de compilación se compensan con un rendimiento estable. Para utilidades pequeñas que se inician rara vez y por períodos cortos, JIT puede ser más ventajoso: la instalación rápida y el poco espacio ocupado son más importantes que el rendimiento máximo.

CriterioAOTJIT
InicioInstantáneoCon calentamiento
InstalaciónMás lenta (compilación)Rápida
Espacio en disco+15–30%Mínimo
Consumo energéticoEstablePicos durante compilación
AdaptabilidadBajaAlta

Rendimiento del código

Un matiz interesante: el código AOT no siempre es más rápido que JIT. JIT tiene acceso a información de perfil en tiempo de ejecución: tipos de objetos precisos, frecuencias de llamada, patrones de ramificación reales. Esto permite aplicar optimizaciones no disponibles en AOT (por ejemplo, inline guiado por perfil). En la práctica, la diferencia de rendimiento del código compilado entre AOT y JIT es de ±5–10% según el escenario.

Ventajas de la compilación AOT

AOT proporciona tres ventajas clave para las aplicaciones móviles. Primera: rendimiento predecible. El usuario no ve “tartamudeos” en los primeros segundos: la aplicación funciona a máxima velocidad desde el primer fotograma. Esto es crítico para juegos, animaciones e interfaces con transiciones suaves.

Segunda: eficiencia energética. AOT no crea picos de carga de CPU típicos de la compilación JIT. El procesador funciona en modo estable, reduciendo el consumo de energía en un 10–15% durante los primeros 30–60 segundos de uso de la aplicación. Para un usuario típico que inicia 20–30 aplicaciones al día, esto proporciona un aumento notable en la duración de la batería.

Simplificación del runtime

La compilación AOT simplifica el entorno de ejecución. Cuando todo el código ya está compilado, no es necesario un compilador JIT, intérprete ni perfilador en tiempo de ejecución. Esto reduce el tamaño del propio runtime y disminuye la probabilidad de errores. ART en modo AOT completo utiliza aproximadamente un 15% menos de RAM que un entorno similar con JIT activo.

Desventajas de la compilación AOT

La principal desventaja de AOT es el tiempo de instalación. En dispositivos antiguos con Android 5.0, instalar aplicaciones grandes (100–200 MB) podía tardar 2–5 minutos debido a la compilación AOT. Esto generaba una experiencia de usuario negativa: después de descargar el APK, los usuarios tenían que esperar antes de abrir la aplicación. Google resolvió parcialmente este problema en Android 7.0 pasando a un esquema híbrido.

La segunda desventaja es el espacio en disco. Los archivos OAT son 15–30% más grandes que los archivos DEX originales. En dispositivos con 8–16 GB de almacenamiento interno, cada aplicación “consume” espacio adicional en la partición del sistema. Para usuarios con una gran cantidad de aplicaciones instaladas (50–100), esto puede provocar falta de espacio para las actualizaciones del sistema.

Falta de adaptabilidad

El código AOT se fija en el momento de la compilación. Si la aplicación utiliza diferentes patrones de ejecución según la versión de Android, el modelo de dispositivo o la configuración del usuario, AOT no puede adaptarse. Las optimizaciones elegidas para un escenario pueden ser subóptimas para otro. JIT es más flexible en este aspecto: recompila los métodos hot cuando cambian las condiciones de ejecución.

AOT más allá de Android: Flutter, .NET, Go

La compilación AOT no solo se utiliza en Android. Flutter usa AOT para compilar código Dart a código nativo para iOS y Android. Esto garantiza un rendimiento de la UI de 60 fps incluso en dispositivos de gama baja. Durante el desarrollo, Flutter usa JIT (hot reload), y para las compilaciones de lanzamiento, AOT, combinando las ventajas de ambos enfoques.

En el ecosistema de .NET, la tecnología ReadyToRun (R2R) permite compilar ensamblados en código nativo por adelantado. Esto reduce el tiempo de inicio de las aplicaciones .NET en un 30–50%. El compilador de Go es inherentemente un compilador AOT: los programas Go se compilan en un único binario estático sin dependencias externas, lo que los hace ideales para entornos de contenedores.

dart
// Flutter: compilación AOT de Dart a código nativo
// La compilación de lanzamiento usa AOT
flutter build apk --release

// Resultado: libapp.so con código Dart compilado con AOT
// El desarrollo usa JIT (hot reload)
flutter run

AOT y seguridad

Una ventaja adicional de AOT es dificultar la ingeniería inversa. El código nativo compilado es más difícil de descompilar que el bytecode. Herramientas como JADX y APKTool funcionan con el formato DEX, pero no pueden recuperar el código fuente de los archivos OAT con el mismo nivel de detalle. Esto no reemplaza la ofuscación (ProGuard, R8), pero crea una barrera adicional para los analizadores.

Estrategia híbrida: compilación perfilada

El estándar moderno en Android es la compilación AOT perfilada, implementada en ART a partir de Android 7.0. Al instalar, la aplicación no se compila completamente; en su lugar, se utiliza una verificación rápida de bytecode y JIT para los primeros inicios. Esto resuelve el problema de la instalación larga, característico de AOT puro en Android 5.0–6.0.

Después de 2–3 inicios de la aplicación, el perfilador de ART recopila datos sobre el uso real y determina qué métodos son más críticos para el rendimiento. Luego, en segundo plano (generalmente por la noche cuando el dispositivo se está cargando), dex2oat compila estos métodos hot en código nativo. Después de la compilación en segundo plano, la aplicación alcanza un rendimiento equivalente al de AOT completo, sin afectar negativamente la experiencia del usuario durante la instalación.

kotlin
// Control programático del modo de compilación (Android 9+)
fun requestProfileCompilation(context: Context) {
    val pm = context.packageManager
    // Se recomienda usar compilación perfilada
    pm.setComponentEnabledSetting(
        ComponentName(context, javaClass()),
        PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
        PackageManager.DONT_KILL_APP
    )
}

Optimización para modo híbrido

Para maximizar los beneficios de la compilación híbrida, los desarrolladores deben seguir algunas reglas. Utilice perfiles base (baseline profiles): perfiles recopilados previamente que se incluyen con el APK y permiten que ART inicie la compilación AOT de métodos hot inmediatamente después de la instalación. Los perfiles base reducen el tiempo para alcanzar el rendimiento completo de 2–3 inicios al primer inicio.

Preguntas frecuentes

¿Qué es la compilación AOT en términos sencillos?

AOT es convertir un programa en código machine por adelantado, antes de que el usuario lo ejecute. Imagine que un libro se traduce completamente a su idioma antes de abrirlo: lo lee de inmediato, sin demoras por la traducción de páginas.

¿En qué se diferencia AOT de JIT?

AOT compila el código durante la instalación (instalación más lenta, pero inicio más rápido). JIT compila el código en tiempo de ejecución (instalación rápida, pero los primeros segundos son más lentos). Los sistemas modernos combinan ambos enfoques.

¿Por qué Android cambió de Dalvik a ART con AOT?

Google quería eliminar el problema del calentamiento de JIT: retrasos en los primeros segundos de ejecución de la aplicación. La compilación AOT en ART proporcionó un inicio instantáneo y redujo el consumo de energía, lo que era críticamente importante para los dispositivos móviles.

¿Cómo afecta AOT al tamaño de la aplicación?

El tamaño del APK no cambia: la compilación AOT crea archivos OAT en la partición del sistema que son 15–30% más grandes que los archivos DEX originales. El usuario ve esto como una reducción del espacio libre de almacenamiento interno, no como un aumento del tamaño del archivo de descarga.

¿Qué es la compilación AOT perfilada?

Es un enfoque híbrido en el que los primeros inicios de la aplicación usan JIT, y luego el sistema compila solo los métodos utilizados con frecuencia en código nativo en segundo plano. Esto combina la instalación rápida de JIT con el alto rendimiento de AOT.

Resumen

  • AOT (Ahead-Of-Time) — compilación de bytecode a código machine antes de la ejecución del programa, en la etapa de instalación.
  • En Android, AOT se implementa mediante la utilidad dex2oat, creando binarios ELF (archivos OAT).
  • Principales ventajas de AOT: inicio instantáneo, rendimiento estable y bajo consumo de energía.
  • Principales desventajas: mayor tiempo de instalación y espacio en disco adicional del 15–30%.
  • AOT se utiliza no solo en Android, sino también en Flutter (Dart), .NET (R2R) y Go.
  • El ART moderno usa AOT perfilado: JIT para primeros inicios, compilación en segundo plano de métodos hot.
  • Los perfiles base permiten iniciar la compilación AOT de métodos clave inmediatamente después de la instalación de la aplicación.

Desarrollaremos una aplicación móvil llave en mano

IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.

Discutir el proyecto

Lea también