Corrigir problemas de memória

Saiba como usar o Microsoft Edge e o DevTools para encontrar problemas de memória que afetam o desempenho da página, incluindo vazamentos de memória, bloat de memória e coletas de lixo frequentes.

  • Descubra a quantidade de memória que sua página está usando no momento com o Gerenciador de Tarefas do Microsoft Edge Browser.
  • Visualize o uso de memória ao longo do tempo com a ferramenta Memória .
  • Identifique árvores DOM desanexadas (uma causa comum de vazamentos de memória) com o Heap instantâneo.
  • Descubra quando a nova memória está sendo alocada no heap do JavaScript (heap JS) com instrumentação de alocação em linha do tempo.

Consulte também Depurar vazamentos de memória DOM com a ferramenta Elementos Desapegados.

Visão geral

No espírito do modelo de desempenho rail , o foco de seus esforços de desempenho deve ser seus usuários.

Problemas de memória são importantes porque geralmente são percebíveis pelos usuários. Os usuários podem perceber problemas de memória das seguintes maneiras:

  • O desempenho de uma página fica progressivamente pior com o tempo. Isso é possivelmente um sintoma de um vazamento de memória. Um vazamento de memória é quando um bug na página faz com que a página use progressivamente mais e mais memória ao longo do tempo.

  • O desempenho de uma página é consistentemente ruim. Isso é possivelmente um sintoma de bloat de memória. O bloat de memória é quando uma página usa mais memória do que o necessário para a velocidade ideal da página.

  • O desempenho de uma página é atrasado ou parece pausar com frequência. Isso é possivelmente um sintoma de coletas de lixo frequentes. A coleta de lixo é quando o navegador recupera a memória. O navegador decide quando isso acontece. Durante as coleções, todo o script em execução é pausado. Portanto, se o navegador estiver coletando muito lixo, o runtime do script será muito interrompido.

Bloat de memória: quanto é "demais"?

Um vazamento de memória é fácil de definir. Se um site estiver usando cada vez mais memória, você terá um vazamento. Mas o bloat de memória é um pouco mais difícil de fixar. O que qualifica como "usar muita memória"?

Não há números difíceis aqui, porque diferentes dispositivos e navegadores têm recursos diferentes. A mesma página que é executada sem problemas em um smartphone high-end pode falhar em um smartphone low-end.

A chave aqui é usar o modelo RAIL e focar em seus usuários. Descubra quais dispositivos são populares entre seus usuários e teste sua página nesses dispositivos. Se a experiência for consistentemente ruim, a página poderá estar excedendo os recursos de memória desses dispositivos.

Monitorar o uso de memória em tempo real com o Gerenciador de Tarefas do Microsoft Edge Browser

Use o Gerenciador de Tarefas do Microsoft Edge Browser como ponto de partida para a investigação do problema de memória. O Gerenciador de Tarefas do Microsoft Edge Browser é um monitor em tempo real que informa a quantidade de memória que uma página está usando no momento.

  1. Pressione Shift+Esc ou vá para o menu microsoft Edge main e selecione Mais ferramentasGerenciador de Tarefas> do Navegador para abrir o Gerenciador de Tarefas do Microsoft Edge Browser.

    Abrir o Gerenciador de Tarefas do Microsoft Edge Browser

  2. Clique com o botão direito do mouse no cabeçalho da tabela do Gerenciador de Tarefas do Microsoft Edge Browser e habilite a memória JavaScript.

    Habilitando a memória JavaScript

Essas duas colunas informam coisas diferentes sobre como sua página está usando a memória:

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

  • A coluna Memória JavaScript representa o heap JS. Esta coluna contém dois valores. O valor que você está interessado é o número ao vivo (o número em parênteses). O número ao vivo representa a quantidade de memória que os objetos acessíveis em sua página estão usando. Se esse número estiver aumentando, novos objetos serão criados ou os objetos existentes estarão crescendo.

Visualizar vazamentos de memória com a ferramenta Desempenho

Você também pode usar a ferramenta Desempenho como outro ponto de partida em sua investigação. A ferramenta Desempenho ajuda você a visualizar o uso de memória de uma página ao longo do tempo.

  1. Em DevTools, abra a ferramenta Desempenho .

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

  3. Faça uma gravação.

É uma boa prática iniciar e terminar sua gravação com uma coleta de lixo forçada. Para forçar a coleta de lixo, clique no botão coletar lixoforçando a coleta de lixo 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, 10.000 div nós são acrescentados ao corpo do documento e uma cadeia de caracteres de 1.000.000 x caracteres é pressionada 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

Primeiro, uma explicação da interface do usuário. O grafo HEAP no painel Visão geral (abaixo do NET) representa o heap JS. Abaixo do painel Visão geral está o painel Contador . O uso da memória é dividido pelo heap JS (mesmo que o gráfico HEAP no painel Visão geral ), documentos, nós DOM, ouvintes e memória GPU. Desmarque uma caixa de seleção para escondê-la do grafo.

Agora, uma análise do código em comparação com a figura anterior. Se você revisar o contador de nós (o grafo verde), ele corresponderá de forma limpa com o código. A contagem de nós aumenta em etapas discretas. Você pode presumir que cada aumento na contagem de nós é uma chamada para grow().

O grafo de heap JS (o grafo azul) não é tão simples. De acordo com as práticas recomendadas, o primeiro mergulho é, na verdade, uma coleta forçada de lixo (clique no botão coletade lixo).

À medida que a gravação progride, os picos de tamanho de heap JS são exibidos. Isso é natural e esperado: o código JavaScript está criando os nós DOM em cada botão que você clica e está fazendo muito trabalho quando cria a cadeia de caracteres de um milhão de caracteres.

O importante aqui é o fato de que o heap JS termina mais alto do que começou (o "começo" aqui sendo o ponto após a coleta forçada de lixo). No mundo real, se você visse esse padrão de aumentar o tamanho ou o tamanho do nó do JS, isso potencialmente indicaria um vazamento de memória.

Descobrir vazamentos de memória de árvore DOM desanexados com Instantâneos de Heap

Um nó DOM só é coletado quando não há referências ao nó da árvore DOM ou do código JavaScript em execução na página. Diz-se que um nó é "desanexado" quando é removido da árvore DOM, mas alguns JavaScript ainda fazem referência a ele. Nós DOM desapegados são uma causa comum de vazamentos de memória.

Esta seção ensina como usar os perfis de heap em DevTools para identificar nós desapegados.

Aqui está um exemplo simples de nós de 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 filhos. Os nós são referenciados pelo código, mas não existem na árvore DOM, portanto, cada nó é desanexado.

Instantâneos de heap são uma maneira de identificar nós desapegados. Como o nome indica, os instantâneos de heap mostram como a memória é distribuída entre os objetos JS e os nós DOM para sua página no momento do instantâneo.

Para criar um instantâneo:

  1. Abra DevTools e vá para a ferramenta Memória .

  2. Clique no botão de rádio Heap instantâneo e clique no botão Tomar instantâneo na parte inferior da ferramenta.

    Tomando um instantâneo de heap

    O instantâneo pode levar algum tempo para processar e carregar.

  3. Depois que o instantâneo for concluído, selecione-o no painel esquerdo (ele se chama HEAP SNAPSHOTS).

  4. Na caixa de texto Filtro de Classe , digite Detached, para pesquisar árvores DOM desanexadas:

    Filtragem para nós desvinculados

  5. Expanda os quilates para investigar uma árvore desanexada:

    Investigando a árvore desapegada

  6. Clique em um nó para investigá-lo ainda mais.

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

  7. Para corrigir o vazamento de memória específico, estude o código que usa a detachedTree variável e verifique se a referência ao nó é removida quando ela não for mais necessária.

Investigando um nó

Identificar vazamentos de memória de heap JS com instrumentação de alocação em linha do tempo

A instrumentação de alocação no linha do tempo é outra ferramenta que pode ajudá-lo a rastrear vazamentos de memória em seu heap JS.

Demonstre a instrumentação de alocação no linha do tempo usando 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, uma cadeia de caracteres de um milhão de caracteres é adicionada à x matriz.

Para registrar uma instrumentação de alocação no linha do tempo:

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

  2. Clique na instrumentação de alocação no botão linha do tempo rádio e clique no botão Iniciar.

  3. Execute a ação que você suspeita estar causando o vazamento de memória.

  4. Quando terminar, clique no botão Parar de gravar o perfil de heapparando a gravação .

  5. Conforme você estiver gravando, observe se as barras azuis aparecem na instrumentação alocação no linha do tempo, como na seguinte figura:

    Novas alocações

    Essas barras azuis representam novas alocações de memória. Essas novas alocações de memória são seus candidatos a vazamentos de memória.

  6. Zoom em uma barra para filtrar o painel Construtor para mostrar apenas objetos que foram alocados durante o período especificado.

    Linha do tempo de alocação com zoom

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

    Por exemplo, na figura a seguir, nos detalhes do objeto recém-alocado indica que ele foi alocado para a x variável no Window escopo:

Detalhes do objeto

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

Use o tipo de criação de perfil de amostragem de alocação para exibir a alocação de memória pela função JavaScript.

Amostragem de alocação de registros

  1. Clique no botão De amostragem de alocação .

  2. Se houver um trabalho na página, você poderá selecioná-lo como o destino de criação de perfil usando o menu suspenso ao lado do botão Iniciar .

  3. Clique no botão Iniciar .

  4. Na página da Web, execute ações que você deseja investigar.

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

DevTools mostra uma divisão da alocação de memória por função. A exibição padrão é Heavy (Bottom Up), que exibe as funções que alocaram mais memória na parte superior.

Amostragem de alocação

Reduzir o lixo com configurações adicionais para amostragem de alocação

Por padrão, o tipo de criação de perfil de amostragem de alocação relata apenas alocações que ainda estão vivas no final da sessão de gravação. Objetos que são criados, removidos e coletados de lixo (GC'd) não são exibidos na ferramenta Memória ao criar perfil usando a amostragem de alocação ou a instrumentação de alocação em linha do tempo tipos.

Você pode confiar no navegador para limpo lixo do código. No entanto, é importante considerar que o GC em si é uma operação cara e vários GCs podem retardar a experiência do usuário em seu site ou aplicativo. Ao gravar na ferramenta Desempenho com a caixa de seleção Memória ativada, você pode ver a operação GC acontecer nas falésias íngremes (reduções repentinas) no gráfico de heap.

Operação GC mostrada na ferramenta Desempenho

Ao reduzir a quantidade de lixo que seu código está criando, você pode reduzir o custo de cada GC individual e o número de operações de GC. Para rastrear objetos descartados pelo GC, configure o tipo de criação de perfil de amostragem de alocação com configurações.

  1. Clique no botão Opção De amostragem de alocação .

  2. Clique nos objetos Incluir descartados pelos principais objetos GC e Include descartados por configurações de GC menores .

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

  3. Clique no botão Iniciar .

  4. Na página da Web, execute ações que você deseja investigar.

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

DevTools agora rastreia todos os objetos que foram GC'd durante a gravação. Use essas configurações para entender quanto lixo seu site ou aplicativo está gerando. Os dados relatados pela amostragem de alocação ajudarão você a identificar as funções que estão gerando mais lixo.

Se você estiver investigando objetos que foram apenas GC'd durante operações específicas de GC principais ou menores, configure as configurações adequadamente para acompanhar a operação com a qual você se importa. Para saber mais sobre as diferenças entre o GC principal e o menor, confira Conversa de lixo: o coletor de lixo Orinoco | Blog do desenvolvedor do mecanismo JavaScript V8.

Detectar coletas de lixo frequentes

Se sua página aparecer para pausar com frequência, você poderá ter problemas de coleta de lixo.

Você pode usar o Gerenciador de Tarefas do Microsoft Edge Browser ou gravações de memória de desempenho para detectar coleta de lixo frequente.

  • No Gerenciador de Tarefas do Microsoft Edge Browser, valores de Memória ou Memória JavaScript em ascensão frequentes representam coleta de lixo frequente.

  • Em gravações de desempenho, alterações frequentes (subindo e caindo) para os grafos de contagem de nó ou heap do JS indicam coleta de lixo frequente.

Depois de identificar o problema, você pode usar uma instrumentação de alocação em linha do tempo gravação para descobrir onde a memória está sendo alocada e quais funções estão causando 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 é encontrada aqui e é de autoria de Kayce Basques (Technical Writer, Chrome DevTools & Lighthouse).

Licença Creative Commons Este trabalho é licenciado sob uma Licença Internacional de Atribuição do Creative Commons 4.0.