Android Runtime (ART) é o ambiente de execução de aplicativos Android, introduzido no Android 5.0 Lollipop como substituto do Dalvik. A principal inovação é a compilação AOT (ahead-of-time) do bytecode DEX em código de máquina nativo diretamente durante a instalação do aplicativo, eliminando o antigo problema de aquecimento do compilador JIT. De acordo com Google, 2024, o ART proporciona um aumento de desempenho de 20–30% em comparação com o Dalvik, mantendo total compatibilidade retroativa com o formato DEX.
Pontos principais
Android Runtime (ART) é um ambiente de execução de aplicativos que compila bytecode DEX em código de máquina nativo antes da execução. Ao contrário do Dalvik, que usava compilação Just-In-Time durante a execução, o ART realiza compilação Ahead-Of-Time (AOT) durante a instalação do APK. Esta mudança arquitetônica fundamental levou a uma aceleração significativa dos aplicativos e à redução do consumo de energia.
O ART apareceu pela primeira vez como uma opção experimental no Android 4.4 KitKat. Os desenvolvedores podiam ativá-la nas configurações do desenvolvedor e testar seus aplicativos. No Android 5.0 Lollipop, o ART se tornou o runtime padrão, e o Dalvik foi completamente removido da plataforma. Quando o Android 7.0 Nougat foi lançado, o ART recebeu um modo de compilação híbrida.
A decisão de substituir o Dalvik pelo ART não foi repentina. O trabalho no novo runtime começou em 2012, quando o Google reconheceu as limitações da abordagem JIT. Principais objetivos: acelerar a inicialização de aplicativos, reduzir a carga da CPU e diminuir o consumo de energia. O desenvolvimento foi liderado pelo Android Runtime Group, que anteriormente trabalhava em otimizações do Dalvik.
O ART usa a mesma arquitetura baseada em registradores que o Dalvik, mas com um compilador completamente redesenhado. Em vez de um interpretador e compilador JIT, o ART inclui o compilador AOT dex2oat, que converte arquivos DEX em binários ELF durante a instalação. Como resultado, os aplicativos no ART iniciam com desempenho nativo imediatamente, sem fase de aquecimento.
O ART manteve os princípios-chave do Dalvik: isolamento de aplicativos por meio de processos separados, arquitetura baseada em registradores e suporte ao formato DEX. No entanto, a implementação interna foi completamente reescrita. Em vez do interpretador Dalvik, o ART inclui três modos de execução: interpretador, compilador JIT e compilador AOT dex2oat. A seleção do modo depende do estágio do ciclo de vida do aplicativo.
O componente-chave do ART é o dex2oat (dalvik executable to optimized android translator). Este utilitário é executado durante a instalação do aplicativo (desde Android 7.0 — também durante a otimização em segundo plano). O dex2oat lê os arquivos DEX do APK, otimiza o bytecode e gera um arquivo OAT — um binário ELF com código nativo. Os arquivos OAT são armazenados no diretório /data/dalvik-cache/.
# Verificar arquivos OAT no dispositivo
adb shell ls -la /data/dalvik-cache/arm64/
# Recompilação forçada do aplicativo
adb shell cmd package compile -m speed com.example.app
O sistema ART consiste em vários módulos interconectados. O compilador dex2oat é responsável pela geração de código nativo. O coletor de lixo (GC) gerencia a desalocação de memória. O interpretador executa código chamado com pouca frequência sem compilação. O perfilador rastreia métodos ativos para compilação híbrida. Cada módulo pode operar independentemente, tornando o ART flexível e escalável.
A partir do Android 7.0 Nougat, o ART usa uma abordagem híbrida de compilação, combinando as vantagens do JIT e do AOT. Durante a instalação do aplicativo, o ART não realiza mais compilação AOT completa — em vez disso, o aplicativo é executado em modo interpretado com compilação JIT de métodos ativos. Isso reduz o tempo de instalação e o espaço de armazenamento.
Um perfilador em segundo plano trabalha em paralelo. Ele coleta estatísticas de execução: quais métodos são chamados com mais frequência, quais ramos de código são executados, quais classes são carregadas. Após acumular dados suficientes (geralmente após 2–3 execuções do aplicativo), o ART executa o dex2oat em segundo plano e compila apenas os métodos ativos perfilados em código nativo.
O ART suporta vários modos de compilação, gerenciados pelo system_server. O modo “speed” compila todos os métodos com AOT (máximo desempenho, instalação lenta). O modo “speed-profile” compila apenas os métodos ativos perfilados (equilíbrio entre velocidade e tamanho). O modo “verify” apenas verifica o bytecode sem compilação (espaço mínimo, interpretação). Por padrão, speed-profile é usado — ideal para a maioria dos aplicativos.
| Modo | Compilação | Tempo de instalação | Desempenho |
|---|---|---|---|
| speed | AOT completa | Lento | Máximo |
| speed-profile | AOT perfilada | Rápido | Alto |
| verify | Sem compilação | Instantâneo | Interpretação |
| space | AOT mínima | Médio | Médio |
O perfilador coleta dados de execução em arquivos .prof especiais. Cada aplicativo armazena seu perfil em /data/misc/profiles/. Quando o limite é atingido (geralmente 1000 amostras), o perfilador executa o dex2oat para compilar os métodos ativos identificados. Os perfis são preservados entre atualizações de aplicativos, acelerando a reotimização após atualizações OTA do sistema.
A coleta de lixo no ART foi dramaticamente melhorada em comparação com o Dalvik. Em vez do Concurrent Mark and Sweep (CMS) de thread única, o ART usa um coletor geracional com várias otimizações: coletor móvel (compactação de heap), espaço de objetos grandes (armazenamento separado para objetos grandes) e compactação concorrente (compactação paralela).
Uma pausa típica de GC no ART é de 2–3 ms contra 5–10 ms no Dalvik. Isso se tornou possível graças a vários mecanismos. Primeiro, o ART usa read-barrier em vez de stop-the-world para fases concorrentes. Segundo, o coletor geracional processa apenas a geração jovem de objetos na maioria dos ciclos, sem tocar em todo o heap. Terceiro, o espaço de objetos grandes (LOS) é alocado separadamente e não participa dos ciclos regulares de GC.
// Ativar logs de GC para depuração
System.logV("ART", "GC trigger: allocation failed");
// Chamada forçada de GC (não recomendada em produção)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Debug.getRuntimeIStats();
}
Apesar do GC melhorado, os vazamentos de memória continuam sendo um problema relevante. Uma causa específica do ART é o carregamento de bibliotecas nativas via JNI sem desalocação adequada. Se o código nativo aloca memória via malloc, mas não chama free, o ART não pode liberar essa memória — ela está fora do heap gerenciado. A ferramenta AddressSanitizer no Android NDK ajuda a identificar esses vazamentos.
ART e Dalvik são duas implementações fundamentalmente diferentes da mesma tarefa: executar aplicativos Android. As diferenças afetam todos os níveis: da compilação ao gerenciamento de memória. Abaixo está uma comparação dos principais parâmetros de desempenho e compatibilidade.
A principal vantagem do ART é a eliminação do aquecimento JIT. No Dalvik, um aplicativo podia ficar lento nos primeiros 3–10 segundos enquanto o JIT compilava métodos ativos. No ART, todos os métodos já estão compilados em código nativo (ou serão compilados em segundo plano). Isso é especialmente perceptível em jogos e aplicativos com UI pesada: a diferença de fps pode chegar a 15–20% a favor do ART.
| Parâmetro | Dalvik | ART |
|---|---|---|
| Compilação | JIT (durante a execução) | AOT + híbrida (na instalação) |
| Tempo de inicialização | 3–10 s (aquecimento) | Instantâneo |
| Tamanho do APK | ~6–7 MB (DEX) | +20% (OAT) |
| Pausas de GC | 5–10 ms | 2–3 ms |
| Consumo de energia | Maior (JIT aquece a CPU) | Menor (código nativo) |
Todos os aplicativos escritos para Dalvik funcionam no ART sem alterações. O Google garante compatibilidade retroativa total no nível do bytecode DEX. A exceção é o código que usa API interna específica do Dalvik via reflexão: membros da classe dalvik.system.DexFile marcados com @hide no Android SDK. Esse código deve ser atualizado para usar APIs públicas.
O ART se tornou o primeiro runtime Android com suporte nativo a recursos Java 8. A partir do Android 7.0, o ART inclui desugaring — o processo de conversão de construtos Java 8 (lambdas, referências de método, Stream API) em código Java 7 equivalente. Isso permite usar sintaxe moderna sem perder compatibilidade com dispositivos mais antigos.
O desugaring é realizado pelo compilador D8 e funciona da seguinte forma. O código-fonte com um lambda é convertido em um método sintético dentro da mesma classe, e o lambda é substituído por uma chamada invoke-custom. O runtime do ART inclui suporte para a instrução invoke-custom, adicionada especificamente para Java 8. Em dispositivos com Android 6.0 e inferior, os lambdas são desugarados em classes anônimas.
// Lambda Java 8 — desugaring no ART
button.setOnClickListener(v -> handleClick(v));
// Após desugaring (equivalente em Java 7)
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handleClick(v);
}
});
Nem todos os recursos Java 8 são suportados pelo desugaring. A API java.time (datas e hora) está disponível apenas através do desugar_jdk_libs — uma biblioteca adicional adicionada ao build.gradle. Stream API também requer desugar_jdk_libs. java.util.function e Optional funcionam sem dependências adicionais. O suporte completo ao Java 8 está disponível em dispositivos com Android 8.0 e superior sem desugaring.
Embora o ART seja compatível retroativamente, algumas práticas de otimização melhoram o desempenho especificamente neste runtime. A principal recomendação é minimizar a reflexão. O ART compila métodos visíveis em tempo de compilação em chamadas diretas de código de máquina. A reflexão força o ART a gerar stubs adicionais, retardando a execução em 10–15%.
A partir do Android 9.0, o ART introduziu suporte para App Startup Optimization. O desenvolvedor pode marcar classes de inicialização no manifesto através de <initialization>, e o ART as pré-carregará na inicialização do aplicativo. Isso reduz o tempo de inicialização em 5–15% para aplicativos com muitos plugins ou bibliotecas.
<!-- App Startup Optimization no AndroidManifest.xml -->
<application>
<profileable
android:shell="true"
android:enable="true" />
</application>
Para medir o desempenho no ART, use systrace e perfetto. Systrace mostra o tempo de compilação do dex2oat, a frequência de GC e a velocidade de renderização de quadros. Perfetto fornece informações mais detalhadas: distribuição de threads, tempo de transições JNI, carregamento de bibliotecas nativas. Execução: adb shell perfetto -o /data/misc/perfetto-traces/trace.perfetto -t 10s sched freq idle am wm.
Perguntas frequentes
ART (Android Runtime) é o ambiente de execução de aplicativos Android que compila o código do aplicativo em código de máquina durante a instalação. Isso acelera a inicialização e operação dos aplicativos em comparação com o antigo runtime Dalvik.
ART compila o código antecipadamente (AOT) durante a instalação do aplicativo, enquanto o Dalvik o compilava peça por peça durante a execução (JIT). Portanto, no ART, os aplicativos iniciam mais rápido e consomem menos energia.
Execute adb shell getprop e encontre a propriedade persist.sys.dalvik.vm.lib.2. O valor “libart.so” significa ART, “libdvm.so” significa Dalvik. Todos os dispositivos com Android 5.0+ usam ART como runtime.
Minimamente. O aplicativo em si permanece no formato APK com arquivos DEX. O ART cria um arquivo OAT adicional em /data/dalvik-cache/, que ocupa 10–20% mais espaço que o DEX original, mas esse armazenamento não está incluído no tamanho do APK.
Sim, o ART suporta a maioria dos recursos Java 8 através do mecanismo de desugaring. Lambdas, referências de método e interfaces funcionais funcionam em todos os dispositivos com Android 5.0+. Stream API e java.time requerem a biblioteca desugar_jdk_libs.
Resumo
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.
Leia também