Uso da memória de bitmap

Os bitmaps costumam ser os maiores objetos que consomem memória em um app. As operações de decodificação e escalonamento geralmente estão no caminho crítico para a renderização de frames. A otimização do uso da memória de bitmap oferece melhorias significativas na capacidade de resposta da interface, na duração da bateria e na estabilidade geral, reduzindo janks, ANRs e encerramentos de processos relacionados a OOM.

Identificar o alto uso da memória de bitmap

O Android vitals fornece métricas sobre o consumo de memória de bitmap de um app agregando dados de dispositivos Android. Essas métricas incluem percentis baseados em períodos (por exemplo, 28 dias) por pacote e processo. Esses dados ajudam a identificar tendências e possíveis regressões na eficiência da memória em diferentes tipos e versões de dispositivos.

O Android vitals compartilha o uso da memória de bitmap do seu app dividido pelos seguintes estados de processo:

  • Primeiro plano: o processo do app está visível. É esperado que o P99 seja significativamente maior em primeiro plano do que em outros estados de processo, mas os desenvolvedores precisam investigar se a proporção P99/P50 é significativa (por exemplo, maior que 3,5 vezes), já que isso geralmente aponta para um vazamento de memória de bitmap. Para identificar isso, procure uma divergência entre o uso típico (P50) e o uso atípico (P99). Embora o inchaço geral de recursos aumente a memória de maneira uniforme em todos os percentis, os vazamentos de memória se acumulam ao longo do tempo, distorcendo muito os dados finais (P99). Verifique se as alocações de bitmap em primeiro plano não persistem desnecessariamente depois que o app faz a transição para outros estados.
  • Serviços percebidos pelo usuário: o processo do app está em execução em um estado perceptível. Isso inclui serviços em primeiro plano, jobs acelerados e jobs de transferência de dados iniciados pelo usuário. Os apps não podem manter alocações de bitmap em primeiro plano pesadas ao fazer a transição para esses estados. Como esses serviços são projetados para tarefas de longa duração, manter recursos grandes degrada a experiência geral do usuário e força o daemon Low Memory Killer (LMKD) a recuperar a memória encerrando processos de menor prioridade.
  • Segundo plano: o app está executando um serviço em segundo plano ou foi colocado em segundo plano recentemente , mas ainda não está em cache. Como esse estado de processo é menos importante do que os processos em primeiro plano ou perceptíveis, os apps precisam liberar explicitamente recursos de bitmap grandes aqui para reduzir a pressão da memória.
  • Em cache: o app está em um estado em cache. Esse estado é altamente sensível à pressão da memória do sistema, como LMKs. Os apps precisam reduzir proativamente o uso da memória de bitmap nesse estado para evitar a remoção pelo SO.

Colaboradores para o alto uso da memória de bitmap

A memória virtual que nunca foi usada também pode ser incluída no cálculo. Se você notar um uso inesperadamente alto da memória de bitmap, verifique se não está alocando memória que não é usada.

Recursos

Analisar bitmaps no Android Studio

Criação de perfil do Android Studio para bitmaps

Use o Memory Profiler para inspecionar alocações de memória em tempo real, capturar heap dumps e analisar objetos em busca de vazamentos de memória. Além disso, use o analisador de heap para detectar vazamentos de memória, identificar alocações de bitmap duplicadas e visualizar a retenção de objetos.

Detecção automática de vazamentos com o LeakCanary

Integre a biblioteca LeakCanary para automatizar a detecção de vazamentos de memória no seu app. O LeakCanary fornece análise automática de heap, identificando objetos que deveriam ter sido coletados como lixo, mas ainda estão na memória, como bitmaps retidos por atividades ou fragmentos destruídos.

Documentação de desempenho de bitmap

Esses recursos fornecem orientações abrangentes sobre as práticas recomendadas para o tratamento eficiente de bitmaps em diferentes componentes do Android.

Lista de verificação do desenvolvedor para otimizar o uso da memória de bitmap

Para otimizar a eficiência da memória de bitmap, siga os três princípios básicos: reduzir, reutilizar e reciclar.

  • Reduzir: minimize a ocupação inicial da memória ao carregar ou exibir bitmaps.
  • Reutilizar: implemente mecanismos de armazenamento em cache para evitar alocações de bitmap redundantes.
  • Reciclar: libere recursos proativamente para permitir a realocação de memória para processos ativos.

A lista de verificação do desenvolvedor a seguir pode ajudar você a otimizar o uso da memória de bitmap.

Princípio básico Área Descrição
Reduzir Eliminar bitmaps duplicados Analise heap dumps usando o Memory Profiler para detectar alocações de bitmap redundantes. Consulte o guia Gerenciar a memória de bitmap.
Aproveitar bibliotecas de carregamento de imagens Use bibliotecas como Glide e Coil para automatizar a criação de linhas de execução, o armazenamento em cache e a decodificação eficiente.
Implementar a redução de amostragem Decodifique imagens para corresponder às dimensões do contêiner da interface de destino em vez de carregar recursos de resolução total.
Usar RGB_565 para imagens opacas Reduza o consumo de memória em 50% alternando de ARGB_8888 para uma configuração de 16 bits para imagens sem transparência.
Priorizar VectorDrawables Use vetores para ícones e gráficos básicos para garantir um escalonamento nítido com sobrecarga mínima de memória.
Otimizar a entrega de imagens do lado do servidor Configure APIs de back-end para veicular imagens adaptadas à densidade do dispositivo e às dimensões da ImageView.
Eliminar margens transparentes Evite alocar memória para pixels "invisíveis" usando InsetDrawable ou preenchimento de layout em vez de margens integradas. Consulte Criar apps Android com bom desempenho de memória.
Reutilizar Configurar tamanhos de cache ideais Adapte os limites de memória e cache em disco com base na RAM do dispositivo e na resolução da tela. Consulte Armazenar bitmaps em cache.
Reciclar Limpar recursos em segundo plano Implemente TRIM_MEMORY_BACKGROUND para limpar caches e melhorar a sobrevivência do processo durante a pressão da memória do sistema.
Liberar recursos quando a interface estiver oculta Use TRIM_MEMORY_UI_HIDDEN para liberar caches de bitmap quando o app não estiver mais visível para o usuário.
Monitorar vazamentos de memória Use o LeakCanary e o Memory Profiler para encontrar bitmaps retidos após a destruição do LifecycleOwner. Consulte Gerenciar a memória do seu app.