O Google tem o compromisso de promover a igualdade racial para as comunidades negras. Saiba como.

Configuração de RAM baixa

O Android oferece suporte a dispositivos com 512 MB de RAM. Esta documentação tem como objetivo ajudar os OEMs a otimizar e configurar o kernel do Android 4.4 para dispositivos com pouca memória. Várias dessas otimizações são genéricas o suficiente para que também possam ser aplicadas a versões anteriores.

Otimizações da plataforma do kernel 4.4 do Android

Gerenciamento de memória aprimorado

  • Configurações de kernel para economia de memória validadas: Trocar para zram.
  • Interrompa os processos em cache se eles estiverem prestes a ser removidos do cache e se forem muito grandes.
  • Não permita que grandes serviços sejam colocados de volta na classificação A Services (para que não possam interromper o inicializador).
  • Interrompa processos (mesmo os que normalmente não podem ser interrompidos, como o IME atual) que ficam muito grandes na manutenção ociosa.
  • Serialize o lançamento de serviços em segundo plano.
  • Ajuste o uso de memória de dispositivos com pouca RAM: níveis de ajuste de falta de memória (OOM) mais restritos, caches de gráficos menores.

Memória de sistema reduzida

  • Aparado system_server e processos de interface do usuário System (salvo vários megabytes).
  • Caches dex pré-carregados em Dalvik (salvou vários megabytes).
  • Opção JIT-off validada (economiza até 1,5 MB por processo).
  • Redução da sobrecarga do cache de fonte por processo.
  • Introduzido ArrayMap / ArraySet e usado extensivamente na estrutura como um substituto mais leve pegada para HashMap / HashSet .

Procstats

Adicionada uma opção do desenvolvedor para mostrar o estado da memória e o uso de memória do aplicativo classificados de acordo com a frequência de execução e a quantidade de memória consumida.

API

Adicionado ActivityManager.isLowRamDevice() para permitir que aplicativos para detectar quando executados em dispositivos de baixa memória e optar por desativar recursos em grande RAM.

Rastreamento de memória

Adicionado HAL memtrack para controlar as alocações de memória gráfica, informações adicionais em dumpsys meminfo, resumos esclarecidas em meminfo (por exemplo, relatou RAM livre inclui RAM de processos em cache, de modo que os OEMs não tentar otimizar a coisa errada).

Configuração de tempo de construção

Sinalizador de dispositivo de pouca RAM

O ActivityManager.isLowRamDevice() flag determina se aplicativos deve desligar características específicas que exigem muita memória que o trabalho mal em dispositivos de baixa memória.

Para 512 dispositivos MB, esta bandeira é esperado para retornar true . Ele pode ser habilitado pela seguinte propriedade do sistema no makefile do dispositivo.

PRODUCT_PROPERTY_OVERRIDES += ro.config.low_ram=true

Configurações do lançador

A configuração padrão papel de parede no lançador não deve usar papel de parede ao vivo. Dispositivos com pouca memória não devem pré-instalar papéis de parede animados.

Configuração do kernel

Ajuste do kernel / ActivityManager para reduzir a recuperação direta

A recuperação direta acontece quando um processo ou o kernel tenta alocar uma página de memória (diretamente ou devido a uma falha em uma nova página) e o kernel usou toda a memória livre disponível. Isso requer que o kernel bloqueie a alocação enquanto libera uma página. Este, por sua vez, muitas vezes requer disco I / O para expulsar uma página de arquivo com backup sujo ou esperar por lowmemorykiller para parar um processo. Isso pode resultar em E / S extra em qualquer thread, incluindo um thread de IU.

Para evitar recuperação direta, o kernel tem marcas d'água que desencadeiam kswapd ou o fundo de recuperação. Este é um encadeamento que tenta liberar páginas para que da próxima vez que um encadeamento real for alocado, ele possa ter sucesso rapidamente.

O limite padrão para acionar a recuperação em segundo plano é bastante baixo, cerca de 2 MB em um dispositivo de 2 GB e 636 KB em um dispositivo de 512 MB. O kernel recupera apenas alguns megabytes de memória na recuperação em segundo plano. Isso significa que qualquer processo que aloca rapidamente mais do que alguns megabytes terá uma recuperação direta rapidamente.

O suporte para um kernel ajustável é adicionado no branch do kernel Android-3.4 como patch 92189d47f66c67e5fd92eafaa287e153197a454f ("adicionar kbytes extras ajustáveis ​​gratuitos"). Cherry-picking este patch para o kernel do um dispositivo permite ActivityManager para dizer ao kernel para tentar manter três full-screen 32 buffers bpp de memória livre.

Estes limiares podem ser configuradas com o config.xml quadro.

<!-- Device configuration setting the /proc/sys/vm/extra_free_kbytes tunable
in the kernel (if it exists).  A high value will increase the amount of memory
that the kernel tries to keep free, reducing allocation time and causing the
lowmemorykiller to kill earlier.  A low value allows more memory to be used by
processes but may cause more allocations to block waiting on disk I/O or
lowmemorykiller.  Overrides the default value chosen by ActivityManager based
on screen size.  0 prevents keeping any extra memory over what the kernel keeps
by default.  -1 keeps the default. -->
<integer name="config_extraFreeKbytesAbsolute">-1</integer>
<!-- Device configuration adjusting the /proc/sys/vm/extra_free_kbytes
tunable in the kernel (if it exists).  0 uses the default value chosen by
ActivityManager.  A positive value  will increase the amount of memory that the
kernel tries to keep free, reducing allocation time and causing the
lowmemorykiller to kill earlier.  A negative value allows more memory to be
used by processes but may cause more allocations to block waiting on disk I/O
or lowmemorykiller.  Directly added to the default value chosen by
ActivityManager based on screen size. -->
<integer name="config_extraFreeKbytesAdjust">0</integer>

Ajustando LowMemoryKiller

ActivityManager configura os limiares da LowMemoryKiller para corresponder a sua expectativa do conjunto de trabalho de páginas baseadas em arquivos (páginas em cache) necessário para executar os processos em cada balde nível de prioridade. Se um dispositivo tiver altos requisitos para o conjunto de trabalho, por exemplo, se a IU do fornecedor requer mais memória ou se mais serviços foram adicionados, os limites podem ser aumentados.

Os limites podem ser reduzidos se muita memória estiver sendo reservada para páginas com backup de arquivo, de forma que os processos de segundo plano sejam eliminados muito antes de ocorrer a fragmentação do disco devido ao cache ficando muito pequeno.

<!-- Device configuration setting the minfree tunable in the lowmemorykiller
in the kernel.  A high value will cause the lowmemorykiller to fire earlier,
keeping more memory in the file cache and preventing I/O thrashing, but
allowing fewer processes to stay in memory.  A low value will keep more
processes in memory but may cause thrashing if set too low.  Overrides the
default value chosen by ActivityManager based on screen size and total memory
for the largest lowmemorykiller bucket, and scaled proportionally to the
smaller buckets.  -1 keeps the default. -->
<integer name="config_lowMemoryKillerMinFreeKbytesAbsolute">-1</integer>
<!-- Device configuration adjusting the minfree tunable in the
lowmemorykiller in the kernel.  A high value will cause the lowmemorykiller to
fire earlier, keeping more memory in the file cache and preventing I/O
thrashing, but allowing fewer processes to stay in memory.  A low value will
keep more processes in memory but may cause thrashing if set too low.  Directly
added to the default value chosen by          ActivityManager based on screen
size and total memory for the largest lowmemorykiller bucket, and scaled
proportionally to the smaller buckets. 0 keeps the default. -->
<integer name="config_lowMemoryKillerMinFreeKbytesAdjust">0</integer>

Trocar para zram

A troca zram pode aumentar a quantidade de memória disponível no sistema compactando as páginas de memória e colocando-as em uma área de troca alocada dinamicamente. Isso troca o tempo de CPU por um pequeno aumento de memória, portanto, considere esse fato ao avaliar o impacto de desempenho que uma troca zram tem em seu sistema.

O Android lida com a troca para zram em vários níveis.

  • Primeiro, habilite essas opções de kernel para usar a troca zram efetivamente:
    • CONFIG_SWAP
    • CONFIG_ZRAM
  • Adicionar uma linha parecida com esta no seu fstab:
    /dev/block/zram0 none swap defaults zramsize=<size in bytes>,swapprio=<swap partition priority>
    
    • zramsize é obrigatório e indica a quantidade de memória não comprimido que você quer a área de zram de espera. Você pode esperar taxas de compressão na faixa de 30-50%.
    • swapprio é opcional e apenas para uso se você tem mais de uma área de troca.

    Rotular o dispositivo de bloqueio associado como um swap_block_device nas específicas do dispositivo sepolicy/file_contexts de modo que ela é tratada adequadamente por SELinux.

    /dev/block/zram0 u:object_r:swap_block_device:s0
    
  • Por padrão, o kernel do Linux troca oito páginas de memória por vez. Ao usar zram, o custo incremental da leitura de uma página por vez é insignificante e pode ajudar se o dispositivo estiver sob extrema pressão de memória. Para ler apenas uma página de cada vez, adicione o seguinte ao seu init.rc :
    write /proc/sys/vm/page-cluster 0
    
  • Em sua init.rc após a mount_all /fstab.X linha, adicione:
    swapon_all /fstab.X
    
  • Os cgroups de memória são configurados automaticamente no momento da inicialização se o recurso estiver habilitado no kernel.
  • Se cgroups de memória estão disponíveis, ActivityManager marcas de menor prioridade tópicos como sendo mais swappable que outros tópicos. Se a memória não é necessário, o kernel do Android começa a migrar páginas de memória para trocar zram, dando uma prioridade maior para as páginas de memória que foram marcados por ActivityManager .

Carveouts, íons e alocação de memória contígua (CMA)

Em dispositivos com pouca memória, é importante estar atento aos carveouts, especialmente aqueles que não são totalmente usados, como um carveout para reprodução de vídeo segura. Existem várias soluções para minimizar o impacto de suas regiões de entalhe que dependem dos requisitos exatos de seu hardware.

Se o hardware permitir alocações de memória descontíguas, o heap do sistema Ion permite alocações de memória da memória do sistema, eliminando a necessidade de um carveout. O íon também tenta fazer grandes alocações para eliminar a pressão do buffer lookaside de tradução (TLB) nos periféricos. Se as regiões de memória devem ser contíguas ou confinadas a um intervalo de endereço específico, o CMA pode ser usado.

Isso cria um entalhe que o sistema também pode usar para páginas móveis. Quando a região é necessária, as páginas móveis são migradas para fora dela, permitindo que o sistema use um grande entalhe para outros fins quando for gratuito. Você pode usar o CMA diretamente com o heap Ion CMA.

Dicas de otimização de aplicativos

Compreenda os vários estados de processo no Android

Estado Significado Detalhes
SERVICE
SERVICE_RESTARTING
Aplicativos executados em segundo plano por motivos relacionados ao aplicativo. SERVICE SERVICE_RESTARTING são a maioria dos problemas comuns aplicativos têm quando executado em segundo plano muito. Use% Duração * pss ou duração% como uma "maldade" métrica. Idealmente, esses aplicativos não deveriam estar em execução.
IMPORTANT_FOREGROUND
RECEIVER
Aplicativos em execução em segundo plano (não interagindo diretamente com o usuário). Isso adiciona carga de memória ao sistema. Utilizar a (% * duração PSS) valor "maldade" a fim estes processos. No entanto, muitos desses aplicativos são executados por bons motivos. O tamanho do pss é uma parte importante da sua carga de memória.
PERSISTENT Processo de sistema persistente. Acompanhe pss para observar esses processos ficando muito grande.
TOP O processo com o qual o usuário está interagindo no momento. pss é a métrica importante aqui, mostrando a quantidade de memória de carga do aplicativo cria durante o uso.
HOME
CACHED_EMPTY
Os processos que o sistema mantém para o caso de serem necessários novamente. Esses processos podem ser eliminados livremente a qualquer momento e recriados se necessário. O estado da memória (normal, moderado, baixo, crítico) é calculado com base em quantos desses processos o sistema está executando. A chave métrica para esses processos é o pss. Nesse estado, esses processos diminuem suas pegadas de memória tanto quanto possível, para permitir que o número total máximo de processos seja mantido. Neste estado, um aplicativo bem comportado geralmente tem uma pegada pss significativamente menor do que no TOP estado.
CACHED_ACTIVITY
CACHED_ACTIVITY_CLIENT
Quando comparado com o TOP , estes mostram o quão bem um aplicativo libera memória para o fundo. Excluindo CACHED_EMPTY estado faz com que esses dados melhor, porque remove situações em que o processo já foi iniciado por algumas razões além de interagir com o usuário. Isso elimina lidar com a sobrecarga UI CACHED_EMPTY começa quando as atividades relacionadas ao usuário.

Análise

Analisando o tempo de inicialização do aplicativo

Para analisar o tempo de inicialização do aplicativo, executar $ adb shell am start -P ou --start-profiler e começar a sua aplicação. O criador de perfil é iniciado depois que o processo é bifurcado do zigoto e antes de qualquer código ser carregado na bifurcação.

Analisando usando relatórios de bug

Relatórios de erros contêm vários serviços, incluindo batterystats , netstats , procstats e usagestats , que pode ser usado para depuração. Os relatórios podem incluir linhas como esta:

------ CHECKIN BATTERYSTATS (dumpsys batterystats --checkin) ------
7,0,h,-2558644,97,1946288161,3,2,0,340,4183
7,0,h,-2553041,97,1946288161,3,2,0,340,4183

Verificação de quaisquer processos persistentes

Para verificar qualquer processo persistente, reinicie o dispositivo e verifique os processos. Em seguida, execute o dispositivo por algumas horas e verifique os processos novamente. Não deve haver nenhum processo de longa duração entre as duas verificações.

Executando testes de longevidade

Para executar testes de longevidade, execute o dispositivo por períodos mais longos e rastreie a memória dos processos para determinar se ela aumenta ou permanece constante. Em seguida, crie casos de uso canônicos e execute testes de longevidade nesses cenários.