O ajuste de desempenho do Android (2) requer conhecimento de Dalvik e ART

Depois de aprender a JVM, aprenda sobre as máquinas virtuais Dalvik e ART em execução em dispositivos móveis. Depois de aprender DVM e ART, você pode otimizar o desenho.
Dalvik e ART também são sistemas muito grandes. Para o desenvolvimento de aplicativos Android, você só precisa dominar seus princípios básicos e examinar seus logs.
Este artigo apresenta apenas o básico: se você quiser saber mais, deve ler livros profissionais.

O ART nasceu no Android 4.4, o DVM e o ART podem ser substituídos na versão 4.4. Após o Android 5.0, o Android executa a máquina virtual como ART por padrão.Neste ponto, o DVM sai do estágio da história.
Em 2020, entre os usuários do Android em todo o mundo, as versões acima de 5,0 representam 87 a 90%. Mesmo que o DVM não tenha sido atualizado, é necessário que aprendamos o DVM. Há muitas coisas comuns à ART. E é mais conveniente entender as características e desvantagens do DVM e vamos explorar por que o ART se torna uma nova biblioteca de tempo de execução de baixo nível.

1. Máquina virtual Dalvik

A Dalvik Virtual Machine, ou DVM, é uma máquina virtual desenvolvida pelo Google especificamente para a plataforma Android e é executada na biblioteca de tempo de execução do Android.

1.1 A diferença entre DVM e JVM

O DVM é uma JVM? A resposta é ----- não! Porque ---- Porque o DVM não segue a especificação da JVM para alcançar.
Ao listar suas diferenças, podemos conhecer as características do DVM.

1. Diferentes
JVMs baseadas em arquitetura são baseadas em pilha , o que significa que a JVM precisa ir para a pilha para ler e gravar dados, e são necessárias mais instruções. A plataforma do PC tem bom desempenho, por isso não parece muito. Mas para dispositivos móveis com desempenho limitado, não é muito adequado.
O DVM é baseado em registros , não requer um grande número de instruções de acesso à pilha, usadas para copiar dados, como mecanismos baseados em pilha, cujas instruções são mais compactas e concisas.
Porém, como o visor especifica os operandos, as instruções baseadas em registro serão maiores que as instruções baseadas na estação base, mas, como o número de instruções diminui, o número total de códigos não aumenta muito.

2. Execute bytecode diferente
sabemos JVM está executando .classo arquivo, em seguida, JVM para identificar e diretamente.
Usará o DVM ferramenta dx tudo vai .classconverter o arquivo em um .dexarquivo e, em seguida, a partir do DVM vai .dexler as instruções e dados de arquivos. A ordem de execução é .java->. Class->. Dex.
Então, por que você quer fazer mais?
Isso ocorre porque o Java .jararquivo que contém uma série de .classarquivos, quando carregadas pela JVM este .jartempo, tudo o que vai ser para carregar .classarquivos. Para projetos particularmente grandes e grandes, essa JVM será muito lenta para carregar, o que não é adequado para dispositivos móveis com memória inicial.
Então .apkarquivo existe apenas um .dexarquivo, o .dexarquivo irá conter todos os .classarquivos: ferramenta DEX vai se livrar de .classtoda a informação redundante, e colocar tudo .classem um único .dexarquivo, reduzindo as operações de I / O para acelerar a classe busca de velocidade .

3. O
DVM permite que vários processos sejam executados simultaneamente na memória limitada.O DVM é otimizado para permitir que vários processos sejam executados simultaneamente na memória prioritária.
Cada aplicativo no Android é executado em uma instância do DVM e cada instância do DVM é executado em um controle de processo independente.Um processo independente impede que todos os programas sejam fechados quando a máquina virtual trava.
Na JVM, um processo é uma JVM.

4. O
DVM é criado e inicializado pelo Zygote O Zygote é um processo do DVM e também é usado para criar e inicializar instâncias do DVM.
Sempre que o sistema precisar criar um aplicativo, o Zygote se esforçará para criar e inicializar rapidamente uma instância do DVM para que o aplicativo seja executado.
Para algumas bibliotecas de sistema somente leitura, todas as instâncias do DVM compartilham uma área de memória com o Zygote, economizando sobrecarga de memória.

5. O
DVM possui um mecanismo de compartilhamento O DVM possui um mecanismo de compartilhamento de pré-carregamento, aplicativos diferentes podem compartilhar a mesma classe em tempo de execução, com maior eficiência.
No entanto, não existe esse mecanismo de compartilhamento no mecanismo da JVM. Programas diferentes são independentes um do outro após serem empacotados.
Mesmo que eles usem a mesma classe no pacote, o tempo de execução é carregado e executado separadamente e não pode ser compartilhado.

6. O DVM não usava o compilador JIT nos primeiros
dias.A JVM usava o compilador JIT (Just in time), enquanto o DVM não usava o compilador JIT nos primeiros dias.
Toda vez que o DVM inicial executava o código, precisava compilar o código dex no código da máquina por meio do intérprete e depois entregá-lo ao sistema, o que não era muito eficiente.
Para resolver esse problema, o DVM começou a usar o JIT no Android 2.2, que irá compilar o código (código do ponto de acesso) que foi executado várias vezes e gerar um código de máquina local relativamente simplificado, para que na próxima vez que a mesma lógica seja executada, a compilação será usada Em vez do código da máquina local que precisa ser compilado todas as vezes.

Deve-se observar que toda vez que o aplicativo é reexecutado, o trabalho de compilação deve ser refeito, portanto, toda vez que o aplicativo é reaberto, a compilação JIT é necessária.

1.2 arquitetura DVM

O código fonte do DVM está localizado no diretório dalvik /.Algumas descrições de diretório são as seguintes:

  • Android.mk
    é um makefile compilado pela máquina virtual
  • A VM
    contém a maior parte do código da máquina virtual, incluindo o código de inicialização e gerenciamento de memória da máquina virtual

  • ferramenta de geração dx para converter código de máquina Java bytecode em DVM
  • hit
    gera ferramentas para exibir informações da pilha / informações do objeto
  • libdex
    gera uma biblioteca para hosts e dispositivos para processar arquivos dex
  • Dexopt
    gera ferramenta de otimização de dex
  • Ferramenta de visualização de descompilação de arquivos
    gerada pelo Dexdump .dex, usada principalmente para verificar a correção e a estrutura do código compilado
  • dexlist
    Este diretório é uma ferramenta para gerar métodos para visualizar todas as classes no arquivo dex

  • .dexprojeto gerador de código de arquivo dexgen
  • docs
    documentos de ajuda relacionados ao DVM

  • Algumas ferramentas relacionadas à compilação e operação

  • Arquivo de aviso de direitos autorais MODULE_LICENSE_APACHE2 APACHE2
  • AVISO
    arquivo de aviso de direitos autorais do código fonte da máquina virtual

Que libdexserão compilados em libdex.auma biblioteca estática, como ferramenta de dex. A arquitetura DVM é mostrada abaixo:
Insira a descrição da imagem aqui

1.3 Pilha de tempo de execução do DVM

A pilha de tempo de execução do DVM usa o algoritmo de marcação e varredura para GC.
Consiste em dois espaços e várias estruturas de dados auxiliares. Os dois espaços são Zygote Space (Zygote Heap) e Allocation Space (Active Heap). A seguir, é apresentada a descrição deles.

  • O Zygote Space é
    usado para gerenciar vários objetos pré-carregados e criados durante a inicialização do processo do Zygote.O GC não será acionado no Zygote Space.
    O Zygote Space é compartilhado entre o processo do Zygote e o processo de aplicação. Antes do primeiro processo filho da bifurcação do processo Zygote, o Zygote Space será dividido em duas partes: a parte original do heap usado ainda é chamada Zygote Space e a parte não utilizada do heap é chamada Allocation Space.
  • Todos os
    objetos após o Espaço de Alocação serão alocados e liberados no Espaço de Alocação. O espaço de alocação não é compartilhado entre processos e cada processo possui sua própria cópia.
  • A tabela de cartões é
    usada para o GC simultâneo do DVM Quando a marcação de lixo é realizada pela primeira vez, as informações de lixo são registradas
  • O Bitmap de Heap
    possui dois Bitmaps de Heap, um é usado para gravar o último objeto ativo do GC, o outro é usado para registrar este objeto ativo do GC

  • A pilha de tempo de execução do Mark Stack DVM usa um algoritmo de marcação e varredura para o GC.O Mark Stack é usado durante a fase de marcação do GC e é usado para atravessar os objetos sobreviventes.

1.4 Logs de GC do DVM

Os logs do GC do DVM e ART são muito diferentes dos logs da JVM.
Cada coleta de lixo no DVM imprimirá os logs do GC no logcat, o formato específico é:

D/dalvikv: <GC_Reason> <Amount_freed>, <Heap_stats>, <External_memory_stats>, <Pause_time>

Você pode ver que existem 5 informações no log do DVM, entre as quais existem muitos tipos de Motivo da GC, que serão introduzidos separadamente aqui.
1. A causa do GC O motivo do GC
é a causa do GC. Existem as seguintes.

  • GC_CONCURRENT: Quando o heap começa a encher, o GC simultâneo pode liberar memória
  • GC_FOR_MALLOC: Quando a pilha de memória está cheia, o aplicativo tenta alocar a memória causada pelo GC, o sistema deve parar o aplicativo e recuperar a memória.
  • GC_HPROF_DUMP_HEAP: GC que aparece quando você solicita a criação do arquivo HPROF para analisar a memória heap
  • GC_EXPLITCIT: GC exibido. Por exemplo, chamadaSystem.gc()
  • GC_EXTERNAL_ALLOC: aplicável apenas ao GC com API <= 10 e usado para memória alocada externamente

2. Outras informações

  • Amout_freed
    O tamanho da memória liberada por este GC
  • Heap_stats
    porcentagem de memória livre de heap: (memória usada) / (memória total de heap)

  • API External_memory_stats <= 10 alocação de memória (memória alocada) / (limite que causa o GC)
  • Tempo de pausa Tempo de
    pausa, um heap maior terá um tempo de pausa mais longo. O tempo de pausa simultâneo exibirá dois tempos de pausa, um no início da coleta de lixo e o outro no final da coleta de lixo.

3. Análise de exemplo
Pegue o GC no logcat como um exemplo:

D/dalvikvm: GC_CONCURRENT freed 2012k, 63% free 3213K/9291K, external 4501K/5161K, paused 2ms+2ms

Significando: A causa do GC é GC_CONCURRENT.A memória liberada por este GC é 2012KB, a porcentagem de memória livre no heap é de 63%, a memória usada é 3213K, a memória total do heap é 9291K e a duração total da pausa é de 4ms

2.ART máquina virtual

ART substituiu completamente o DVM no Android 5.0

2.1 A diferença entre ART e DVM

  • Cada vez que o aplicativo é executado no DVM, o bytecode precisa ser compilado no código da máquina através do JIT, o que reduzirá a eficiência operacional do aplicativo e, no sistema, o sistema executará a pré-compilação do bytecode uma vez ao instalar o aplicativo.AOT(ahead of time compilation,预编译) Ele é compilado no código da máquina e armazenado localmente, para que o aplicativo não precise executar a compilação toda vez que o programa é executado, e a eficiência da execução é bastante aprimorada. O consumo de energia do dispositivo também será reduzido.
    Existem também duas desvantagens principais no uso do pré-carregamento do AOT:
    Primeiro, o AOT aumentará o tempo de instalação do lado do aplicativo.Em
    segundo lugar, o bytecode é pré-compilado no código da máquina e o código da máquina precisa de mais espaço de armazenamento (aqui há espaço para o tempo) )
    Para solucionar as deficiências acima, o ART é adicionado ao JIT na versão Android 7.0. Como um complemento ao AOT, todos os bytecodes não são compilados no código da máquina quando o aplicativo é instalado, mas os pontos ativos estão em operação. O código é compilado no código da máquina, o que reduz o tempo de instalação do aplicativo e economiza espaço de armazenamento.
  • O DVM foi projetado para CPU de 32 bits, e o ART suporta 64 bits e é compatível com a CPU de 32 bits, que é um dos principais motivos para a eliminação do DVM
  • O ART melhorou o mecanismo de coleta de lixo, como executar o GC com mais frequência, reduzindo a pausa do GC de dois para um
  • A divisão de espaço de heap de tempo de execução da ART é diferente do DVM

2.2 Heap de tempo de execução do ART

Diferente do GC da DVM, o ART usa uma variedade de esquemas de coleta de lixo, cada esquema executa um coletor de lixo diferente, o padrão é o esquema CMS (Concurrent Mark-Sweep), que usa principalmente CMS e CMS parcial, de acordo com diferentes esquemas de CMS, o controle de heap de tempo de execução do ART também será dividido de forma diferente, o padrão é composto de 4 Espaço e várias estruturas de dados auxiliares. Os quatro espaços são espaço zigoto, espaço de alocação, espaço de imagem e espaço de objetos grandes. Os dois primeiros são os mesmos que no DVM.

  • O Image Space é
    usado para armazenar algumas classes pré-carregadas
  • O espaço grande do objeto é
    usado para alocar alguns objetos grandes (o tamanho padrão é 12 KB)

Entre eles, o Zygote Space e o Image Space são espaços compartilhados entre processos.
Além desses quatro Spaces, o heap Java da ART também inclui duas Tabelas de Mod Union, uma Table Card, dois Heap Bitmaps, dois mapas de objetos e três pilhas de objetos

2.3 Registro de GC da ART

A diferença entre o log do GC do ART e o DVM é que o ART imprimirá o log do GC apenas para os eventos de coleta de lixo solicitados ativamente ou quando a velocidade do GC for considerada lenta .
A velocidade lenta do GC significa que o tempo de pausa do GC excede 5 ms ou o tempo de duração do GC excede 100 ms. Se o aplicativo não estiver em um estado de pausa perceptível, seu GC não será considerado lento.
O formato específico do log de GC da ART é:

I/art: <GC_REASON> <GC_NAME> <Objects_freed>(<Size_freed>) AllocSpace Objects, 
<Large_objects_freed>(<Large_object_suze_freed>) <Heap_stats> Losobjects,
<Pause_time(s)>

1. Causas de GC causam
ART mais que DMV

  • O
    GC simultâneo simultâneo não pausa o encadeamento do App. O GC é executado em um encadeamento em segundo plano e não organiza a alocação de memória
  • Alocar
    Quando a memória está cheia, o aplicativo tenta alocar a memória causada pelo GC, este GC ocorrerá no encadeamento que está alocando memória
  • O
    aplicativo explícito mostra solicitações de coleta de lixo, como invocação System.gc().
    Mas queremos evitar mostrar a chamada do GC, devemos confiar no GC. A chamada GC mostrada impedirá a alocação de threads e desperdiçará ciclos de CPU desnecessariamente. Se a solicitação explícita de GC fizer com que outros encadeamentos sejam antecipados, isso pode levar ao jank (o aplicativo desenha várias vezes no mesmo quadro)
  • NativeAlloc
    Alocação de memória nativa, como alocar objetos para Bitmaps ou RenderScript, o que causará pressão na memória nativa e acionará o GC
  • CollectorTransition
    é causado pela conversão de heap, causada pela alternância do GC no tempo de execução. As transições de coletor incluem a cópia de todos os objetos do espaço de lista livre para o espaço do ponteiro de colisão.Atualmente, as transições de coletor ocorrem nas seguintes situações: Em dispositivos com pouca memória, o aplicativo altera o estado do processo de uma pausa perceptível para um estado suspenso. Estado não pausado perceptível
  • A
    compactação homogênea de espaço HomogeneousSpaceCompact refere-se à lista de espaços para o espaço de lista livre compactado, geralmente ocorre quando o aplicativo é movido para um estado visível do processo de pausa. A principal razão para isso é reduzir o uso da memória e desfragmentar a memória heap.
  • DisableMovingGc
    não é realmente o motivo para acionar o GC.Quando ocorre a compactação de heap simultânea, a GetPrimitiveArrayCriticalcoleção será bloqueada devido ao seu uso.Em geral, é altamente recomendável não usá- GetPrimitiveArrayCriticallo porque há restrições quanto à movimentação do coletor
  • HeapTrim
    não é a causa do GC, a coleção será bloqueada até que a memória heap seja resolvida.

2. O nome do coletor de lixo
GC_NAME refere-se ao nome do coletor de lixo

  • Varredura simultânea de marca (CMS) O
    coletor CMS é um coletor que visa obter o menor tempo de pausa na coleta,
    usa um algoritmo de varredura de marca, é uma informação completa sobre o lixo de heap e pode liberar todo o espaço, exceto o Espaço de Imagem.
  • Marca Parcial Simultânea A varredura de
    parte do coletor de lixo completo pode liberar todo o espaço, exceto o Espaço da Imagem e o Espaço Zygote
  • O
    coletor pegajoso simultâneo de varredura de marca pegajosa, com base na ideia de coleta de lixo geracional, só pode liberar os objetos alocados desde o último GC.
    Esse coletor de lixo varre com mais frequência do que um coletor de lixo completo ou parcial porque é mais rápido e tem um tempo de pausa mais curto
  • GC
    não simultâneo Marksweep + Semispace , copie o GC para conversão de heap e compactação de espaço homogênea

3. Outras informações

  • Objetos liberados
    O número de objetos recuperados do espaço de objetos não grande por este GC
  • Size_freed
    O número de bytes recuperados do espaço de objetos não grande por este GC
  • Objetos grandes liberados
    O número de objetos recuperados do Large Object Space por este GC
  • Tamanho do objeto grande liberado
    Número de bytes recuperados do Large Object Space por este GC
  • Estatísticas da pilha
    A porcentagem de memória livre na pilha, ou seja (memória usada) / (memória total da pilha)
  • Tempos de
    pausa Tempo de pausa, o tempo de pausa é proporcional ao número de referências de objetos modificadas enquanto o GC está em execução.
    Atualmente, o coletor de ART do CMS foi suspenso apenas uma vez e ele aparece próximo ao final do GC. Os coletores de lixo móveis serão suspensos por um longo tempo e continuarão a aparecer durante a maioria das coletas de lixo.

4. Análise de caso

I/art: Explicit concurrent mark sweep GC freed 104710(7MB) AllocSpace objects, 21(416KB) LOS objects,
33% free, 25MB/38MB, paused 1.230ms total 67.1ms

Isso significa que o motivo desse GC é explícito, o coletor é CMS, o número de objetos liberados é 104710, o número de bytes liberados é 7MB, o número de objetos grandes liberados é 21 416k e a memória livre do heap é responsável por 33% A memória total é de 38 MB, 25 MB foram usados, o tempo de pausa é de 1,23 ms e o tempo total do GC é de 67,1 ms

No AndroidStudio, você pode visualizar o log abrindo o Logcat e filtrando "gc":

Insira a descrição da imagem aqui

3. Resumo

As duas seções acima descrevem as características do DVM e ART, sua estrutura, heap de tempo de execução, mecanismo de GC e como exibir logs do GC.
Você também pode ver a diferença entre DVM e ART, bem como a diferença entre essas duas máquinas virtuais e a JVM.
Além disso, também precisamos entender como o DVM e o ART são gerados.Como o código-fonte envolvido será relacionado ao Zygote, e meu conhecimento sobre o Zygote não é claro o suficiente, portanto, nesses dois meses, gastamos tempo para Complemente o conhecimento sobre o zigoto.

Publicado 263 artigos originais · 110 elogios · 120.000 visualizações

Acho que você gosta

Origin blog.csdn.net/rikkatheworld/article/details/104051308
Recomendado
Clasificación