AOT — o que é compilação Ahead-Of-Time e como funciona

Autor: IT Sectr Publicado: 2026-04-16 Tempo de leitura: 9 min

AOT (Ahead-Of-Time) — uma tecnologia de compilação onde o código fonte ou bytecode é convertido em instruções de máquina antes da execução do programa, na fase de compilação ou instalação. No Android, a compilação AOT tornou-se uma inovação chave do ambiente de execução ART, que substituiu o Dalvik na versão 5.0 Lollipop. De acordo com a Google, 2024, a compilação AOT no ART elimina atrasos de aquecimento e reduz o consumo de energia das aplicações em 10–15% em comparação com a abordagem JIT.

Pontos principais

  • AOT — compilação Ahead-Of-Time: conversão de código para código de máquina antes da execução do programa.
  • No Android, o AOT é realizado pelo utilitário dex2oat durante a instalação do APK ou em segundo plano.
  • A principal vantagem do AOT é a inicialização instantânea de aplicações sem fase de aquecimento.
  • A desvantagem é o maior tempo de instalação e espaço em disco adicional de 15–30%.
  • Sistemas modernos usam uma abordagem híbrida: JIT para primeiras execuções, AOT para métodos hot.

O que é compilação AOT?

Ahead-Of-Time (AOT) é um método de compilação onde um programa é convertido em código de máquina antes de ser executado. O termo “Ahead-Of-Time” contrasta com JIT (Just-In-Time): se JIT compila “no momento certo,” então AOT compila “antecipadamente.” Um compilador AOT recebe código fonte ou uma representação intermediária (bytecode) como entrada e gera um arquivo executável pronto para uso.

A história do AOT remonta aos compiladores tradicionais de C e C++, onde a compilação sempre ocorre antes da execução. No contexto das linguagens gerenciadas (Java, C#, Dart), o AOT é uma inovação mais recente: por muito tempo, acreditou-se que os recursos dinâmicos (reflexão, carregamento dinâmico de classes) tornavam o AOT difícil de implementar. A Google resolveu esse problema para o Android criando o dex2oat — um compilador AOT de bytecode DEX para código nativo.

Como o AOT funciona

Um compilador AOT realiza um ciclo completo de tradução. O primeiro estágio é a análise sintática e construção de uma árvore sintática abstrata (AST). O segundo é análise e otimização: eliminação de código morto, inlining, otimização de loops. O terceiro é a geração de código de máquina para a arquitetura alvo (ARM, ARM64, x86). O resultado é um arquivo executável que não requer processamento adicional em tempo de execução.

bash
# Execução manual do compilador AOT dex2oat
dex2oat --dex-file=classes.dex \
        --oat-file=classes.oat \
        --arch=arm64 \
        --instruction-set-variant=generic

# Verificar o arquivo OAT compilado
oatdump --oat-file=classes.oat --output=oat_dump.txt

AOT no Android: dex2oat e arquivos OAT

No Android, a compilação AOT é implementada através do utilitário dex2oat (dalvik executable to optimized android translator). Quando um usuário instala uma aplicação, o sistema executa o dex2oat, que lê os arquivos DEX do APK, otimiza o bytecode e cria um arquivo OAT — um binário ELF com código nativo. Este arquivo é salvo na partição /data/dalvik-cache/.

O processo de compilação inclui vários níveis de otimização. O nível básico — verificação de bytecode e otimizações básicas (eliminação de código morto, constant folding). O nível intermediário — inlining de métodos, desenrolamento de loops, análise de escape. O nível máximo — otimizações globais de toda a aplicação, incluindo desvirtualização e otimização do tamanho da pilha. O nível de otimização depende do modo de compilação (speed, speed-profile, space).

Estrutura do arquivo OAT

Um arquivo OAT usa o formato ELF (Executable and Linkable Format) — o mesmo formato usado por binários nativos Linux. Dentro do arquivo OAT está o código compilado para cada método da aplicação, juntamente com metadados: informações sobre classes, campos, métodos e suas relações. O ART usa esses metadados para carregamento rápido de classes e resolução de referências simbólicas sem análise completa de DEX.

Componente OATPropósito
Cabeçalho ELFCabeçalho do formato ELF
Seção de códigoCódigo de máquina de métodos compilados
Cabeçalho OATMetadados ART: versão, tamanhos de seção
Seções DEXDados DEX originais para reflexão
Tabela de ligaçãoTabela de ligação para JNI e bibliotecas nativas

AOT vs JIT: análise comparativa

AOT e JIT representam diferentes pontos no espaço de compromisso entre desempenho e flexibilidade. AOT fornece máxima velocidade de execução desde o primeiro segundo, mas requer mais espaço em disco e tempo de instalação. JIT economiza espaço e tempo de instalação, mas paga com atrasos de aquecimento e picos de consumo de energia.

O fator chave de seleção é o caso de uso. Para aplicações que são iniciadas uma vez e funcionam por muito tempo (jogos, editores, navegação), AOT é preferível — os custos de compilação são compensados pelo desempenho estável. Para utilitários pequenos que raramente são iniciados e funcionam por curtos períodos, JIT pode ser mais vantajoso — instalação rápida e pouco espaço ocupado são mais importantes que o desempenho máximo.

CritérioAOTJIT
InicializaçãoInstantâneaCom aquecimento
InstalaçãoMais lenta (compilação)Rápida
Espaço em disco+15–30%Mínimo
Consumo de energiaEstávelPicos durante compilação
AdaptabilidadeBaixaAlta

Desempenho do código

Uma nuance interessante: o código AOT nem sempre é mais rápido que JIT. JIT tem acesso a informações de perfil em tempo de execução — tipos precisos de objetos, frequências de chamada, padrões reais de ramificação. Isso permite aplicar otimizações indisponíveis para AOT (por exemplo, inlining guiado por perfil). Na prática, a diferença de desempenho do código compilado entre AOT e JIT é de ±5–10% dependendo do cenário.

Vantagens da compilação AOT

AOT fornece três vantagens principais para aplicações móveis. Primeira — desempenho previsível. O usuário não vê “gaguejos” nos primeiros segundos: a aplicação funciona na velocidade máxima desde o primeiro quadro. Isso é crítico para jogos, animações e interfaces com transições suaves.

Segunda — eficiência energética. AOT não cria picos de carga de CPU típicos da compilação JIT. O processador opera em modo estável, reduzindo o consumo de energia em 10–15% durante os primeiros 30–60 segundos de uso da aplicação. Para um usuário típico que inicia 20–30 aplicações por dia, isso proporciona um aumento notável na duração da bateria.

Simplificação do runtime

A compilação AOT simplifica o ambiente de execução. Quando todo o código já está compilado, não há necessidade de um compilador JIT, interpretador ou profilador em tempo de execução. Isso reduz o tamanho do próprio runtime e diminui a probabilidade de erros. O ART em modo AOT completo usa aproximadamente 15% menos RAM do que um ambiente semelhante com JIT ativo.

Desvantagens da compilação AOT

A principal desvantagem do AOT é o tempo de instalação. Em dispositivos antigos com Android 5.0, instalar aplicações grandes (100–200 MB) podia levar de 2–5 minutos devido à compilação AOT. Isso criava uma experiência de usuário negativa: após baixar o APK, os usuários tinham que esperar antes de abrir a aplicação. A Google resolveu parcialmente esse problema no Android 7.0 mudando para um esquema híbrido.

A segunda desvantagem é o espaço em disco. Os arquivos OAT são 15–30% maiores que os arquivos DEX originais. Em dispositivos com 8–16 GB de armazenamento interno, cada aplicação “consome” espaço adicional na partição do sistema. Para usuários com grande número de aplicações instaladas (50–100), isso pode levar à falta de espaço para atualizações do sistema.

Falta de adaptabilidade

O código AOT é fixado no momento da compilação. Se a aplicação usa diferentes padrões de execução dependendo da versão do Android, modelo do dispositivo ou configurações do usuário, o AOT não pode se adaptar. As otimizações escolhidas para um cenário podem ser subótimas para outro. O JIT é mais flexível nesse aspecto: ele recompila métodos hot quando as condições de execução mudam.

AOT além do Android: Flutter, .NET, Go

A compilação AOT não é usada apenas no Android. O Flutter usa AOT para compilar código Dart em código nativo para iOS e Android. Isso garante desempenho de UI a 60 fps mesmo em dispositivos de baixo custo. Durante o desenvolvimento, o Flutter usa JIT (hot reload), e para compilações de lançamento — AOT, combinando as vantagens de ambas as abordagens.

No ecossistema .NET, a tecnologia ReadyToRun (R2R) permite compilar assemblies em código nativo antecipadamente. Isso reduz o tempo de inicialização de aplicações .NET em 30–50%. O compilador Go é inerentemente um compilador AOT: programas Go são compilados em um único binário estático sem dependências externas, tornando-os ideais para ambientes de contêineres.

dart
// Flutter: compilação AOT de Dart para código nativo
// A compilação de lançamento usa AOT
flutter build apk --release

// Resultado: libapp.so com código Dart compilado com AOT
// O desenvolvimento usa JIT (hot reload)
flutter run

AOT e segurança

Uma vantagem adicional do AOT é dificultar a engenharia reversa. O código nativo compilado é mais difícil de descompilar do que bytecode. Ferramentas como JADX e APKTool funcionam com o formato DEX, mas não podem recuperar o código fonte dos arquivos OAT no mesmo nível de detalhe. Isso não substitui a ofuscação (ProGuard, R8), mas cria uma barreira adicional para analisadores.

Estratégia híbrida: compilação perfilada

O padrão moderno no Android é a compilação AOT perfilada, implementada no ART a partir do Android 7.0. Ao instalar, a aplicação não é completamente compilada — em vez disso, a verificação rápida de bytecode e JIT são usados para as primeiras execuções. Isso resolve o problema de instalação longa, característico do AOT puro no Android 5.0–6.0.

Após 2–3 inicializações da aplicação, o profilador do ART coleta dados sobre o uso real e determina quais métodos são mais críticos para o desempenho. Então, em segundo plano (geralmente à noite quando o dispositivo está carregando), o dex2oat compila esses métodos hot em código nativo. Após a compilação em segundo plano, a aplicação atinge desempenho equivalente ao AOT completo, sem impactar negativamente a experiência do usuário durante a instalação.

kotlin
// Controlo programático do modo de compilação (Android 9+)
fun requestProfileCompilation(context: Context) {
    val pm = context.packageManager
    // É recomendado usar compilação perfilada
    pm.setComponentEnabledSetting(
        ComponentName(context, javaClass()),
        PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
        PackageManager.DONT_KILL_APP
    )
}

Otimização para modo híbrido

Para maximizar os benefícios da compilação híbrida, os desenvolvedores devem seguir algumas regras. Use perfis base (baseline profiles) — perfis pré-coletados que acompanham o APK e permitem que o ART inicie a compilação AOT de métodos hot imediatamente após a instalação. Os perfis base reduzem o tempo para atingir o desempenho total de 2–3 inicializações para a primeira inicialização.

Perguntas frequentes

O que é compilação AOT em termos simples?

AOT é converter um programa em código de máquina antecipadamente, antes que o usuário o execute. Imagine que um livro é traduzido inteiramente para o seu idioma antes de abri-lo — você lê imediatamente, sem atrasos para tradução de páginas.

Como o AOT difere do JIT?

AOT compila o código durante a instalação (instalação mais lenta, mas inicialização mais rápida). JIT compila o código em tempo de execução (instalação rápida, mas os primeiros segundos são mais lentos). Sistemas modernos combinam ambas as abordagens.

Por que o Android mudou do Dalvik para o ART com AOT?

A Google queria eliminar o problema de aquecimento do JIT — atrasos nos primeiros segundos de execução da aplicação. A compilação AOT no ART proporcionou inicialização instantânea e reduziu o consumo de energia, o que era criticamente importante para dispositivos móveis.

Como o AOT afeta o tamanho da aplicação?

O tamanho do APK não muda — a compilação AOT cria arquivos OAT na partição do sistema que são 15–30% maiores que os arquivos DEX originais. O usuário vê isso como uma redução no espaço livre de armazenamento interno, não como um aumento no tamanho do arquivo de download.

O que é AOT perfilado?

É uma abordagem híbrida onde as primeiras execuções da aplicação usam JIT, e então o sistema compila apenas os métodos usados com frequência em código nativo em segundo plano. Isso combina a instalação rápida do JIT com o alto desempenho do AOT.

Resumo

  • AOT (Ahead-Of-Time) — compilação de bytecode em código de máquina antes da execução do programa, na fase de instalação.
  • No Android, o AOT é implementado através do utilitário dex2oat, criando binários ELF (arquivos OAT).
  • Principais vantagens do AOT: inicialização instantânea, desempenho estável e baixo consumo de energia.
  • Principais desvantagens: maior tempo de instalação e espaço em disco adicional de 15–30%.
  • AOT é usado não apenas no Android, mas também no Flutter (Dart), .NET (R2R) e Go.
  • O ART moderno usa AOT perfilado: JIT para primeiras execuções, compilação em segundo plano de métodos hot.
  • Os perfis base permitem iniciar a compilação AOT de métodos chave imediatamente após a instalação da aplicação.

Vamos desenvolver um aplicativo móvel chave na mão

A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.

Discutir o projeto

Leia também