Recursos que consomem muita memória

A plataforma Android está baseada no princípio de que memória livre é memória desperdiçada. O Android tenta usar toda a memória disponível em todos os momentos. Por exemplo, o sistema mantém os apps na memória depois de terem sido fechados para que o usuário possa voltar a eles rapidamente. Por esse motivo, os dispositivos Android geralmente são executados com pouca memória livre (consulte Alocação de memória do Android aqui).

O processo do daemon low memory killer (LMK) do Android monitora o estado da memória de um sistema Android em execução e reage à alta pressão na memória encerrando os processos menos essenciais para manter o sistema funcionando em níveis aceitáveis.

Para decidir qual processo encerrar, o daemon LMK usa uma pontuação de memória insuficiente chamada oom_adj_score para priorizar os processos em execução. Os processos com maior pontuação são encerrados primeiro. Os apps em segundo plano são encerrados primeiro, e os processos do sistema, por último. A tabela a seguir lista as categorias de pontuação do LMK, da maior para a menor. Os itens da categoria com maior pontuação na primeira linha são encerrados primeiro:

Processos do Android classificados da maior para a menor pontuação: apps em segundo plano, app anterior, app da tela inicial,
             serviços, apps perceptíveis, app em primeiro plano, persistente, sistema e nativo.
Figura 1. Processos do Android com pontuações mais altas na parte de cima e mais baixas na parte de baixo.

Ferramentas de criação de perfil de memória

As ferramentas a seguir podem ajudar você a encontrar e diagnosticar problemas de memória das seguintes maneiras:

  • Conferir como o app aloca memória ao longo do tempo. Você pode encontrar um gráfico em tempo real de quanta memória o app está usando, o número de objetos Java alocados e quando ocorre a coleta de lixo.
  • Inicie os eventos de coleta de lixo e faça uma captura de tela do heap Java enquanto o app é executado.
  • Registre as alocações de memória do app, inspecione todos os objetos alocados e confira o stack trace para cada alocação.

Se o jogo estiver sendo executado em um mecanismo nativo, use o Limpador de endereços HW para depurar a alocação de memória nativa.

Memory Profiler do Android Studio

O Android Studio oferece o Memory Profiler como um componente do Android Profiler, que ajuda a identificar vazamentos e rotatividade de memória que podem gerar oscilações, travamentos e até falhas no app. O profiler mostra um gráfico em tempo real do uso da memória pelo app e permite capturar um heap dump, forçar a coleta de lixo e rastrear a alocação de memória.

Figura 2. Visualização de referências globais de JNI no Memory Profiler do Android Studio.

Ferramentas de criação de perfil de memória do Unity

Se você estiver usando o Unity Engine para criar seus apps, siga as orientações de criação de perfil de memória do Unity. O Unity oferece duas ferramentas para analisar o uso da memória no seu aplicativo.

O primeiro é o módulo Memory Profiler, um criador de perfil integrado que fornece informações básicas sobre onde o aplicativo usa memória.

O módulo de memória mostra alocações de memória, como memória de textura e memória de malha.
Figura 3. Janela do Unity Profiler com o módulo Memory selecionado.

A segunda ferramenta é o pacote Memory Profiler, que é um pacote do Unity que pode ser adicionado ao seu projeto. O pacote adiciona uma janela extra do Memory Profiler ao Unity Editor. Com o Memory Profiler, você pode analisar o uso da memória no seu aplicativo com ainda mais detalhes. É possível armazenar e comparar snapshots para encontrar vazamentos de memória ou ver o layout da memória e encontrar problemas de fragmentação.

Figura 4. Analisar um instantâneo de memória usando a janela do Memory Profiler.

Unreal Memory Insights

Os apps criados pelo Unreal Engine podem usar o Unreal Memory Insights para conferir informações detalhadas sobre alocação e desalocação de memória, incluindo as tags de memória de baixo nível (LLM) e as callstacks associadas a blocos de memória.

O sistema de consultas do Memory Insights pode encontrar alocações ativas a qualquer momento, identificar mudanças no uso da memória, localizar vazamentos de memória e diferenciar alocações de curto e longo prazo.

A partir do UE 5.4, o Memory Insights oferece suporte ao rastreamento de memória com callstacks para projetos Android.

Rastreador do Memory Insights mostrando o gráfico principal de memória, a contagem de alocações em tempo real e a contagem de eventos de alocação/liberação.
Figura 5. Rastreador do Memory Insights do Unreal.

Insights sobre pouca memória

O Android oferece callbacks e APIs que permitem reduzir os requisitos de memória do jogo e determinar por que as execuções anteriores foram encerradas.

Callbacks

Não registre callbacks trim descontinuados. O Android não tem APIs para detectar eventos de pressão de memória nativa quando o sistema está atingindo os limites de memória. Os callbacks de corte não ajudaram a evitar encerramentos por falta de memória. Por isso, o Android descontinuou todos eles exceto TRIM_MEMORY_UI_HIDDEN e TRIM_MEMORY_BACKGROUND.

Encerramento do jogo

O Android tenta usar toda a memória disponível para armazenar em cache apps e jogos e garantir que eles carreguem rapidamente (melhorando a experiência do usuário). No entanto, quando a memória fica limitada, o sistema encerra os apps e jogos que consomem mais memória para liberar espaço para o funcionamento normal do dispositivo.

Informações, insights e práticas recomendadas para ajudar você a melhorar o uso da memória do jogo:

  • Use ApplicationExitInfo: essa API retorna o motivo pelo qual a execução anterior do jogo foi encerrada pelo sistema Android. Use ApplicationExitInfo para verificar se a falta de memória foi o motivo de uma interrupção de execução de processo anterior. Verifique se o jogo foi encerrado devido à pouca memória para que ele possa ser otimizado para usar menos memória no dispositivo.
  • Analise a RAM física total: para evitar que os jogos sejam encerrados quando estiverem em primeiro plano e para corresponder aos recursos do dispositivo, analise a RAM física total por dispositivo para ter uma granularidade refinada e ajustar o uso da memória do jogo com base nisso. Se o objetivo for impedir que os apps sejam encerrados logo após serem movidos para segundo plano (para permitir que o jogador faça várias tarefas ao mesmo tempo), use os callbacks de trim (TRIM_MEMORY_UI_HIDDEN especificamente) para reduzir o uso da memória do jogo.

Outros recursos