Compartilhar via


Corrigir problemas de memória

Saiba como utilizar o Microsoft Edge e o DevTools para encontrar problemas de memória que afetam o desempenho das páginas, incluindo fugas de memória, sobrecarga de memória e libertações de memória frequentes.

  • Saiba a quantidade de memória que a sua página está a utilizar atualmente com o Gestor de Tarefas do Browser Microsoft Edge.
  • Visualize a utilização da memória ao longo do tempo com a ferramenta Memória .
  • Identifique árvores DOM desanexadas (uma causa comum de fugas de memória) com o instantâneo da Área Dinâmica para Dados.
  • Saiba quando a memória nova está a ser alocada na área dinâmica para dados javaScript (área dinâmica para dados JS) com a instrumentação de Alocação na linha cronológica.

Veja também Depurar fugas de memória DOM com a ferramenta Elementos Desanexados.

Visão geral

No espírito do modelo de desempenho RAIL , o foco dos seus esforços de desempenho deve ser os seus utilizadores.

Os problemas de memória são importantes porque, muitas vezes, são percetáveis pelos utilizadores. Os utilizadores podem ver os problemas de memória das seguintes formas:

  • O desempenho de uma página piora progressivamente ao longo do tempo. Isto é possivelmente um sintoma de fuga de memória. Uma fuga de memória ocorre quando um erro na página faz com que a página utilize cada vez mais memória ao longo do tempo.

  • O desempenho de uma página é consistentemente mau. Isto é possivelmente um sintoma de inchaço da memória. A sobrecarga da memória ocorre quando uma página utiliza mais memória do que a necessária para uma velocidade de página ideal.

  • O desempenho de uma página está atrasado ou parece colocar em pausa com frequência. Este é possivelmente um sintoma de libertações de lixo frequentes. A libertação da memória é quando o browser recupera a memória. O browser decide quando isto acontece. Durante as coleções, todos os scripts em execução são colocados em pausa. Por isso, se o browser estiver a recolher muita memória, o runtime do script será colocado em pausa.

Sobrecarga de memória: quanto é "demasiado"?

É fácil definir uma fuga de memória. Se um site estiver a utilizar cada vez mais memória progressivamente, terá uma fuga. Mas a sobrecarga da memória é um pouco mais difícil de fixar. O que se qualifica como "utilizar demasiada memória"?

Não existem números rígidos aqui, porque diferentes dispositivos e browsers têm capacidades diferentes. A mesma página que funciona sem problemas num smartphone de alta qualidade pode cair num smartphone de gama baixa.

A chave aqui é utilizar o modelo RAIL e concentrar-se nos seus utilizadores. Descubra que dispositivos são populares com os seus utilizadores e, em seguida, teste a sua página nesses dispositivos. Se a experiência for consistentemente má, a página poderá estar a exceder as capacidades de memória desses dispositivos.

Monitorizar a utilização da memória em tempo real com o Gestor de Tarefas do Browser Microsoft Edge

Utilize o Gestor de Tarefas do Browser Microsoft Edge como ponto de partida para a investigação do problema de memória. O Gestor de Tarefas do Browser Microsoft Edge é um monitor em tempo real que indica a quantidade de memória que uma página está a utilizar atualmente.

  1. Prima Shift+Esc ou aceda ao menu principal do Microsoft Edge e selecione Mais ferramentasGestor de Tarefas> do Browser para abrir o Gestor de Tarefas do Browser Microsoft Edge.

    Abrir o Gestor de Tarefas do Browser Microsoft Edge

  2. Clique com o botão direito do rato no cabeçalho da tabela do Gestor de Tarefas do Browser Microsoft Edge e, em seguida, ative a memória JavaScript.

    Ativar a memória JavaScript

Estas duas colunas dão-lhe informações diferentes sobre a forma como a sua página está a utilizar a memória:

  • A coluna Memória representa a memória nativa. Os nós DOM são armazenados na memória nativa. Se este valor estiver a aumentar, os nós DOM estão a ser criados.

  • A coluna Memória de JavaScript representa a área dinâmica para dados JS. Esta coluna contém dois valores. O valor em que está interessado é o número dinâmico (o número entre parênteses). O número dinâmico representa a quantidade de memória que os objetos acessíveis na sua página estão a utilizar. Se este número estiver a aumentar, estão a ser criados novos objetos ou os objetos existentes estão a crescer.

Visualizar fugas de memória com a Ferramenta de desempenho

Também pode utilizar a Ferramenta de desempenho como outro ponto de partida na investigação. A ferramenta Desempenho ajuda-o a visualizar a utilização de memória de uma página ao longo do tempo.

  1. Em DevTools, abra a ferramenta Desempenho .

  2. Selecione a caixa de verificação Memória .

  3. Faça uma gravação.

É uma boa prática começar e terminar a gravação com uma libertação de lixo forçada. Para forçar a libertação da memória, clique no botão recolherlibertação da memória forçada durante a gravação.

Para demonstrar gravações de memória, considere o seguinte código:

var x = [];
function grow() {
    for (var i = 0; i < 10000; i++) {
        document.body.appendChild(document.createElement('div'));
    }
    x.push(new Array(1000000).join('x'));
}
document.getElementById('grow').addEventListener('click', grow);

Sempre que o botão referenciado no código é clicado, são acrescentados 10 000 div nós ao corpo do documento e é enviada uma cadeia de 1000 000 x carateres para a x matriz. A execução do exemplo de código anterior produz uma gravação na ferramenta Desempenho , como a seguinte figura:

Crescimento simples

Em primeiro lugar, uma explicação da interface de utilizador. O gráfico HEAP no painel Descrição Geral (abaixo do NET) representa a área dinâmica para dados JS. Abaixo do painel Descrição Geral encontra-se o painel Contador . A utilização da memória é dividida pela área dinâmica para dados JS (igual ao gráfico HEAP no painel Descrição geral ), documentos, nós DOM, serviços de escuta e memória GPU. Desmarque uma caixa de verificação para ocultá-la do gráfico.

Agora, uma análise do código em comparação com a figura anterior. Se rever o contador de nós (o gráfico verde), este corresponde corretamente ao código. A contagem de nós aumenta em passos discretos. Pode presumir que cada aumento na contagem de nós é uma chamada para grow().

O gráfico de área dinâmica para dados JS (o gráfico azul) não é tão simples. De acordo com as melhores práticas, o primeiro mergulho é, na verdade, uma libertação da memória forçada (clique no botão recolherlibertação da memória da força de lixo ).

À medida que a gravação progride, os picos de tamanho da área dinâmica para dados JS são apresentados. Isto é natural e esperado: o código JavaScript está a criar os nós DOM em cada botão em que clica e está a fazer muito trabalho quando cria a cadeia de um milhão de carateres.

O mais importante aqui é o facto de a área dinâmica para dados JS terminar mais alto do que começou (o "início" aqui é o ponto após a libertação forçada da memória). No mundo real, se vir este padrão de aumento do tamanho da área dinâmica para dados do JS ou do tamanho do nó, poderá indicar uma fuga de memória.

Detetar fugas de memória de árvore DOM desanexadas com Instantâneos de Área Dinâmica para Dados

Um nó DOM só é recolhido da memória quando não existem referências ao nó a partir da árvore do DOM ou do código JavaScript em execução na página. Diz-se que um nó está "desanexado" quando é removido da árvore DOM, mas alguns JavaScript ainda o referenciam. Os nós DOM desanexados são uma causa comum de fugas de memória.

Esta secção ensina-o a utilizar os geradores de perfis de área dinâmica para dados em DevTools para identificar nós desanexados.

Eis um exemplo simples de nós DOM desanexados:

var detachedTree;

function create() {
    var ul = document.createElement('ul');
    for (var i = 0; i < 10; i++) {
        var li = document.createElement('li');
        ul.appendChild(li);
    }
    detachedTree = ul;
}
document.getElementById('create').addEventListener('click', create);

Clicar no botão referenciado no código cria um ul nó com dez li subordinados. Os nós são referenciados pelo código, mas não existem na árvore DOM, pelo que cada nó é desanexado.

Os instantâneos de área dinâmica para dados são uma forma de identificar nós separados. Como o nome indica, os instantâneos de área dinâmica para dados mostram-lhe como a memória é distribuída entre os objetos JS e os nós DOM da sua página no momento do instantâneo.

Para criar um instantâneo:

  1. Abra DevTools e aceda à ferramenta Memória .

  2. Clique no botão de opção Instantâneo da Área Dinâmica para Dados e, em seguida, clique no botão Tirar instantâneo na parte inferior da ferramenta.

    Tirar um instantâneo de área dinâmica para dados

    O instantâneo pode demorar algum tempo a processar e carregar.

  3. Depois de o instantâneo estar concluído, selecione-o no painel esquerdo (chama-se INSTANTÂNEOS DE HEAP).

  4. Na caixa de texto Filtro de classe, escreva Detached, para procurar árvores DOM desanexadas:

    Filtragem de nós desanexados

  5. Expanda os carateiros para investigar uma árvore isolada:

    Investigar a árvore desanexada

  6. Clique num nó para investigar mais aprofundadamente.

    No painel Objetos , pode ver mais informações sobre o código que faz referência ao nó. Por exemplo, na figura seguinte, a detachedTree variável está a referenciar o nó.

  7. Para corrigir a fuga de memória específica, analise o código que utiliza a detachedTree variável e certifique-se de que a referência ao nó é removida quando já não for necessária.

Investigar um nó

Identificar fugas de memória de área dinâmica para dados JS com instrumentação de alocação na linha cronológica

A instrumentação de alocação na linha cronológica é outra ferramenta que pode ajudá-lo a localizar fugas de memória na área dinâmica para dados JS.

Demonstre a instrumentação da Alocação na linha cronológica com o seguinte código:

var x = [];
function grow() {
    x.push(new Array(1000000).join('x'));
}
document.getElementById('grow').addEventListener('click', grow);

Sempre que o botão referenciado no código é clicado, é adicionada uma cadeia de um milhão de carateres à x matriz.

Para registar uma instrumentação de Alocação na linha cronológica:

  1. Abra DevTools e selecione a ferramenta Memória .

  2. Clique no botão de opção Instrumentação de alocação na linha cronológica e, em seguida, clique no botão Iniciar .

  3. Execute a ação que suspeita estar a causar a fuga de memória.

  4. Quando terminar, clique no botão Parar gravação do perfil de área dinâmica para dadosparar gravação.

  5. À medida que estiver a gravar, repare se aparecem barras azuis na instrumentação de Alocação na linha cronológica, como na figura seguinte:

    Novas alocações

    Essas barras azuis representam novas alocações de memória. Essas novas alocações de memória são as candidatas a fugas de memória.

  6. Amplie uma barra para filtrar o painel Construtor para mostrar apenas os objetos que foram alocados durante o período de tempo especificado.

    Linha cronológica de alocação ampliada

  7. Expanda o objeto e selecione o valor para ver mais detalhes no painel Objeto .

    Por exemplo, na figura seguinte, nos detalhes do objeto alocado recentemente indica que foi alocado à x variável no Window âmbito:

Detalhes do objeto

Investigar a alocação de memória por função

Utilize o tipo de criação de perfis de amostragem de alocação para ver a alocação de memória pela função JavaScript.

Amostragem de Alocação de Registos

  1. Clique no botão de opção Amostragem de alocação .

  2. Se existir um trabalho na página, pode selecioná-lo como o destino da criação de perfis, utilizando o menu pendente junto ao botão Iniciar .

  3. Clique no botão Iniciar .

  4. Na página Web, execute as ações que pretende investigar.

  5. Clique no botão Parar quando terminar todas as suas ações.

DevTools mostra-lhe uma discriminação da alocação de memória por função. A vista predefinida é Pesada (Inferior Para Cima), que apresenta as funções que alocaram mais memória na parte superior.

Amostragem de alocação

Reduzir a memória com definições adicionais para a amostragem de alocação

Por predefinição, o tipo de criação de perfis de amostragem de Alocação apenas comunica alocações que ainda estão ativas no final da sessão de gravação. Os objetos criados, removidos e, em seguida, recolhidos pela memória (GC'd) não são apresentados na ferramenta Memória ao criar perfis com a amostragem de Alocação ou a Instrumentação de alocação em tipos de linha cronológica .

Pode confiar no browser para limpar o lixo do seu código. No entanto, é importante considerar que o GC em si é uma operação dispendiosa e que vários GCs podem abrandar a experiência do utilizador no seu site ou aplicação. Ao gravar na ferramenta Desempenho com a caixa de verificação Memória ativada, pode ver que a operação GC ocorre nas falésias íngremes (diminuições repentinas) no gráfico de área dinâmica para dados.

Operação GC apresentada na ferramenta Desempenho

Ao reduzir a quantidade de lixo que o código está a criar, pode reduzir o custo de cada GC individual e o número de operações de GC. Para controlar os objetos que são eliminados pelo GC, configure o tipo de criação de perfis de amostragem de alocação com as definições.

  1. Clique no botão de opção Amostragem de alocação .

  2. Clique em Incluir objetos eliminados pelo GC principal e Incluir objetos eliminados por definições de GC secundárias .

    Definições de GC de amostragem de alocação

  3. Clique no botão Iniciar .

  4. Na página Web, execute as ações que pretende investigar.

  5. Clique no botão Parar quando terminar todas as suas ações.

As DevTools monitorizam agora todos os objetos que foram GC'd durante a gravação. Utilize estas definições para compreender a quantidade de lixo que o seu site ou aplicação está a gerar. Os dados comunicados pela Amostragem de alocação irão ajudá-lo a identificar as funções que estão a gerar mais lixo.

Se estiver a investigar objetos que eram apenas GC'd durante operações de GC principais ou secundárias específicas, configure as definições adequadamente para controlar a operação que lhe interessa. Para saber mais sobre as diferenças entre o gc principal e o menor, consulte Conversa de lixo: o recoletor de lixo Orinoco | Blogue do programador do motor JavaScript V8.

Detetar libertações de lixo frequentes

Se a sua página parecer colocar em pausa com frequência, poderá ter problemas de libertação da memória.

Pode utilizar o Gestor de Tarefas do Browser Microsoft Edge ou gravações de memória de desempenho para detetar a libertação da memória frequente.

  • No Gestor de Tarefas do Browser Microsoft Edge, os valores de Memória ou Memória JavaScript frequentemente crescentes e em queda representam a libertação da memória frequente.

  • Em Gravações de desempenho, as alterações frequentes (subindo e caindo) na área dinâmica para dados do JS ou grafos de contagem de nós indicam a libertação da memória frequente.

Depois de identificar o problema, pode utilizar uma instrumentação de Alocação na gravação da linha cronológica para saber onde a memória está a ser alocada e quais as funções que estão a causar as alocações.

Observação

Partes desta página são modificações baseadas no trabalho criado e compartilhado pelo Google e usadas de acordo com os termos descritos na Licença Pública Creative Commons Atribuição 4.0 Internacional. A página original encontra-se aqui e é criada por Kayce Bascos (Technical Writer, Chrome DevTools & Lighthouse).

Licença Creative Commons Este trabalho é licenciado ao abrigo de uma Licença Internacional creative Commons Attribution 4.0.