Analisando dados de uso de memória (JavaScript)

Este tópico descreve o JavaScript Memory Analyzer. Esta ferramenta está disponível para os aplicativos da Windows Store criados com JavaScript em Atualização 1 do Visual Studio 2012. Para obter um tutorial mostrando como usar a ferramenta, consulte Tutorial: Localizando um vazamento de memória (JavaScript).

Exibindo dados do uso de memória

Você pode usar o JavaScript Memory Analyzer quando há um aplicativo de trabalho da Windows Store aberto no Visual Studio.

Para executar o JavaScript Memory Analyzer

  1. Se você estiver executando o aplicativo no Visual Studio, clique em Computador Local, Simulador ou Computador Remoto na lista suspensa Iniciar Depuração na barra de ferramentas Depurar.

    Para obter mais informações sobre essas opções, consulte Executando aplicativos da Windows Store do Visual Studio.

  2. No menu Depurar, selecione Análise de Memória JavaScript e clique em uma destas opções:

    • Inicializar Projeto de Inicialização. Clique nesta opção para iniciar o projeto de inicialização atual. Se você estiver executando aplicativo em um computador remoto, deverá clicar nesta opção.

    • Inicializar Pacote de Aplicativos Instalado. Clique nesta opção para selecionar um aplicativo instalado que você deseje analisar. Não há suporte para esta opção na execução do aplicativo em um computador remoto.

      Você pode usar esta opção para analisar o uso de memória de aplicativos instalados no seu computador quando você não tem acesso ao código-fonte. Esta opção também pode ser útil quando você deseja apenas analisar o uso de memória de qualquer aplicativo, fora do seu próprio desenvolvimento de aplicativo.

    • Anexar a um Aplicativo em Execução. Clique nesta opção para selecionar o aplicativo de uma lista de aplicativos em execução. This option is not supported when running the app on a remote machine.

      Você pode usar esta opção para analisar o uso de memória de aplicativos em execução no seu computador quando você não tem acesso ao código-fonte.

    Ao iniciar o analisador de memória, você poderá ver o Controle de Conta de Usuário solicitando sua permissão para executar o arquivo VsEtwCollector.exe. Clique em Sim.

  3. Alterne para o Visual Studio pressionando Alt+Tab.

    O Visualização de resumo do JavaScript Memory Analyzer é exibido na guia do hub Diagnóstico.

Modos de exibição de uso de memória

Quando você executa o JavaScript Memory Analyzer, estes modos de exibição de dados do uso de memória estão disponíveis:

  • Visualização de resumo. Fornece um gráfico de uso de memória para o aplicativo em execução e uma coleção de todos os quadros de resumo de instantâneos. Este modo de exibição aparece na guia do hub Diagnóstico.

  • Exibindo detalhes do instantâneo. Mostra dados do uso de memória detalhados para um único instantâneo.

  • Exibindo a diferença de um instantâneo. Mostra dados do uso de memória detalhados como valores diferenciais entre dois instantâneos selecionados.

Visualização de resumo

A exibição resumida fornece um gráfico de uso de memória para o aplicativo em execução e uma coleção de todos os quadros de resumo de instantâneos. Nesta exibição, você pode executar tarefas básicas como obter instantâneos, analisar informações resumidas e navegar para outros modos de exibição.

O gráfico de memória mostra uma exibição em tempo real da memória do processo do aplicativo, que inclui bytes particulares, a memória nativa e o heap de JavaScript. Veja a seguir a aparência do gráfico:

Gráfico de memória do analisador de memória de JavaScript

O gráfico de memória é uma exibição rolável da memória do processo.

Se qualquer marca de perfil foi adicionada ao código do aplicativo, um triângulo Marca do usuário aparecerá no gráfico de uso de memória para indicar quando essa seção do código for atingida. Para obter mais informações, consulte Comandos do console de JavaScript.

Qualquer memória mostrada no gráfico é atribuída pelo tempo de execução JavaScript. Não é possível controlar esse uso de memória do seu aplicativo. O uso de memória mostrado no gráfico aumenta quando você usa o primeiro instantâneo e, em seguida, aumenta em níveis mínimos para cada instantâneo adicional.

Exibindo um resumo de instantâneo

Você pode obter um instantâneo de estado atual do uso de memória do aplicativo clicando em Obter Instantâneo de Heap na exibição resumida. Um quadro de resumo de instantâneo, que também aparece na exibição resumida, fornece informações sobre o heap de JavaScript e links para informações mais detalhadas. Se você tiver dois ou mais instantâneos tirados, um instantâneo fornecerá informações adicionais que comparam seus dados aos dados do instantâneo anterior.

Dica

O JavaScript Memory Analyzer força uma coleta de lixo antes de cada instantâneo. Isso ajuda a garantir que os resultados sejam mais consistente entre as execuções.

Esta ilustração mostra um exemplo de um instantâneo quando já foi obtido um instantâneo anterior.

Resumo de snapshot

Esta é a informação que aparece no resumo de instantâneo:

  • Título do instantâneo e o carimbo de data/hora.

  • Tamanho do heap (texto azul, lado esquerdo). Esse número inclui elementos DOM e objetos que o mecanismo de tempo de execução JavaScript adiciona ao heap de JavaScript. O tamanho do heap é um link para a exibição Dominadores do instantâneo.

  • Tamanho diferencial de heap (texto vermelho ou verde, lado esquerdo). Esse valor mostra a diferença entre o tamanho do heap do instantâneo atual e o do instantâneo anterior. O valor aparece em vermelho se há um aumento de memória; caso contrário, aparece em verde. Se o tamanho do heap for o mesmo, o valor será Nenhuma Dif. Para o primeiro instantâneo, o valor é simplesmente Referência (texto cinza). Esse valor é um link para a exibição Dominadores da diferença do instantâneo.

  • Contagem de objeto (texto azul, lado direito). Essa contagem mostra apenas objetos criados no seu aplicativo, e filtra os objetos internos criados no tempo de execução JavaScript. A contagem de objeto é vinculada à exibição Tipos dos detalhes do instantâneo.

  • Contagem de objeto diferencial (texto vermelho ou verde, lado direito). Esse valor mostra a diferença entre a contagem de objeto do instantâneo atual e a do instantâneo anterior. O valor aparece em vermelho se há um aumento da contagem de objeto; caso contrário, aparece em verde. Se a contagem de objeto for a mesma, o valor será Nenhuma Dif. For the first snapshot, the value is simply Baseline (gray text). Esse valor é um link para a exibição Tipos da diferença do instantâneo.

  • Captura da tela no momento em que o instantâneo é obtido.

Dica

É possível que um resumo de instantâneo não mostre nenhum aumento ou exiba uma diferença negativa entre tamanho/contagem, mas ainda assim pode ocultar uma perda de memória. Isso pode acontecer quando o número/tamanho de objetos recém-criados é menor do que o número/tamanho dos objetos que foram excluídos. Por exemplo, isso pode acontecer como resultado de uma coleta de lixo.

Exibindo detalhes do instantâneo

Você pode exibir informações detalhadas sobre o uso de memória para cada instantâneo na exibição detalhada de instantâneo.

Na exibição resumida, você pode visualizar os detalhes do instantâneo clicando em um link em um resumo de instantâneo. Por exemplo, o link de tamanho do heap em um resumo de instantâneo abre os detalhes do instantâneo, com a exibição Dominadores aberta por padrão.

Esta ilustração mostra a exibição Tipos em um detalhe de instantâneo.

Modo de exibição de detalhes do snapshot mostrando tipos

No modo de exibição de instantâneo detalhada, as seguintes exibições adicionais dos dados de uso de memória estão disponíveis:

  • Dominadores. Mostra uma lista de todos os objetos que estão no heap, classificados pelo tamanho retido.

  • Tipos. Mostra a contagem de instância e o tamanho total de objetos, agrupados pelo tipo de objeto. Por padrão, eles são classificados pela contagem de instância.

  • Raízes. Mostra uma árvore de objetos desde objetos raiz até referências de filhos. Por padrão, os nós filho são classificados pela coluna de tamanho retido, com o maior na parte superior.

  • DOM. Mostra os objetos que são elementos de marcação (DOM) e o tamanho retido. Por padrão, eles são classificados pelo tamanho retido.

  • WinRT. Mostra o objetos gerenciados e não gerenciados Windows que são referenciados no aplicativo JavaScript. By default, these are sorted by retained size.

A maioria das exibições, como a Dominadores, mostra tipos de valores semelhantes. Esses valores são:

  • Identificador(es). Nome que melhor identifica o objeto. Por exemplo, para elementos HTML, mostramos o valor do atributo ID, se um for usado.

  • Tipo. Nome de tipo do objeto.

  • Tamanho. Tamanho do objeto, não incluindo o tamanho de nenhum objeto referenciado.

  • Tamanho Retido. Soma do tamanho do objeto mais o tamanho de todos os objetos filho que não têm nenhum outro objeto pai. Para fins práticos, essa soma é a quantidade de memória retida pelo objeto, então, se você excluir o objeto, recuperará a quantidade de memória especificada.

  • Contagem. O número de instâncias do objeto. Esse valor aparece apenas na exibição Tipos.

Exibindo a diferença de um instantâneo

No JavaScript Memory Analyzer, você pode comparar um instantâneo com um instantâneo anterior em uma exibição diferencial de instantâneo.

Na exibição de resumo, você pode exibir os detalhes diferenciais dos instantâneos clicando em outro instantâneo na lista suspensa no canto superior direito de um quadro de resumo de instantâneo.

A diferença de instantâneo permite que você visualize informações sobre dominadores, tipos, raízes, objetos DOM e objetos do Tempo de Execução do Windows.

A diferença de instantâneo mostra todos os objetos que foram adicionados ao heap entre os dois instantâneos. Na exibição Raízes diferencial (e no Gráfico de Referência), um texto em cinza claro indica que o próprio objeto existia no instantâneo anterior, mas ele tem um filho que não.

Esta ilustração mostra a exibição Dominadores em uma diferença de instantâneo.

Diferencial do instantâneo no modo de exibição de Dominators

Nos modos de exibição diferenciais de instantâneo, exibições como a Dominadores são as mesmas que na exibição Exibindo detalhes do instantâneo. As exibições diferenciais de instantâneo mostram os mesmos tipos de valor que os modos de exibição detalhada, com estes valores adicionais:

  • Dif de Tamanho. Diferença entre o tamanho do objeto no instantâneo atual e seu tamanho no instantâneo de comparação (o instantâneo mais antigo), não incluindo o tamanho de nenhum objeto referenciado.

  • Dif de Tamanho Retido. Diferença entre o tamanho retido do objeto no instantâneo atual e seu tamanho retido no instantâneo de comparação (o instantâneo mais antigo). O tamanho retido inclui o tamanho do objeto mais o tamanho de todos os objetos filho que não têm nenhum outro objeto pai. Para fins práticos, o tamanho retido é a quantidade de memória retida pelo objeto, então, se você excluir o objeto, recuperará a quantidade de memória especificada.

  • Dif de Contagem. Diferença entre o número de instâncias do objeto no instantâneo atual e o número de instâncias no instantâneo de comparação. This value appears only in the Types view.

Apresentação na exibição de raiz

Nas exibições Dominadores, Tipos, DOM e WinRT, você pode ver a relação entre um objeto específico e o objeto Global. Usando esse recurso, você pode localizar facilmente um objeto conhecido na exibição Raízes sem pesquisar a árvore de objeto Global.

Para usar o recurso, clique com o botão direito do mouse em um identificador na exibição Dominadores, Tipo, DOM ou WinRT e clique em Mostrar na exibição de raiz.

Filtrando dados

Nas exibições Dominadores, Tipos, DOM e WinRT, você pode filtrar dados procurando por identificadores específicos. Para procurar por um identificador, basta digitar o valor na caixa de texto Filtro de identificador. Quando você começar a digitar caracteres, os identificadores que não contiverem os caracteres digitados serão removidos.

Cada modo de exibição tem seu próprio filtro, para que as informações filtradas não sejam transferidas para os modos de exibição.

Exibindo referências

Os painéis inferiores dos modos de exibição Dominadores, Tipos, DOM e WinRT contêm um gráfico de referência que você pode usar para visualizar as referências compartilhadas. Se você selecionar um objeto no painel superior, o Gráfico de Referência exibirá uma lista de referências que apontam para o objeto selecionado.

Se você desejar obter ajuda geral para identificar objetos equivalentes, poderá fazê-lo no painel superior, clicando em Exibir IDs de objeto na lista suspensa de configurações no canto superior direito do painel. Quando você clicar nessa opção, as IDs de objetos aparecerão ao lado dos objetos na lista Identificador(es). Os objetos com a mesma ID são referências compartilhadas.

Mostrando valores internos

Nas exibições Dominadores, Tipos, DOM e WinRT, você pode exibir objetos internos. Por padrão, esses modos de exibição mostram apenas a objetos criados em seu aplicativo. Isso ajuda a filtrar informações desnecessárias e isolar problemas relacionados ao aplicativo. No entanto, às vezes pode ser útil exibir todos os objetos que são geradas para seu aplicativo pelo tempo de execução JavaScript. Você pode exibir esses objetos no JavaScript Memory Analyzer.

Para exibir esses objetos, clique em Mostrar internos na lista suspensa de configurações no canto superior direito do painel.

Arquivos de sessão de diagnóstico

Os resumos de instantâneo de diagnóstico, juntamente com as exibições detalhadas associadas, são salvos como arquivos .diagsession. O Gerenciador de Soluções exibe sessões de diagnóstico anteriores na pasta Sessões de Diagnóstico. No Gerenciador de Soluções, você pode abrir sessões anteriores, remover ou renomear arquivos.

Comandos do console de JavaScript

O JavaScript Memory Analyzer oferece suporte a dois Comandos do console de JavaScript que você pode usar em seu código para ajudar a isolar a seção de código na qual um problema de memória está ocorrendo. Esses comandos lançarão uma exceção se você adicioná-los ao aplicativo e executá-lo em qualquer contexto diferente do analisador de memória (embora você possa testar se os comandos existirem antes de usá-los). Os comandos não existirão no início da fase de inicialização da sessão.)

  • console.takeHeapSnapshot obtém um instantâneo de heap que aparece no JavaScript Memory Analyzer.

  • console.profileMark define uma marca de perfil (o triângulo Marca do Usuário) que aparece na linha de tempo do gráfico de memória na exibição resumida. Esse comando usa um argumento de cadeia de caracteres que representa uma descrição do evento, e aparece como uma dica de ferramenta no gráfico de memória. Essa descrição não deve exceder 100 caracteres.

O exemplo de código a seguir mostra como você pode chamar takeHeapSnapshot com segurança.

    if (console && console.takeHeapSnapshot) { console.takeHeapSnapshot(); }

O exemplo de código a seguir mostra como você pode chamar profileMark com segurança.

    if (console && console.profileMark) { console.profileMark("Initialized"); }

Dicas para identificar problemas de memória

Estas dicas podem ajudá-lo a diagnosticar problemas de uso de memória:

  • Use a exibição Dominadores de uma diferença de instantâneo para tentar identificar rapidamente os principais problemas de memória.

  • Use Apresentação na exibição de raiz para ajudar a identificar onde um objeto é referenciado na hierarquia de memória geral.

  • Quando a causa do problema de memória é difícil de identificar, use as diversas exibições (como Dominadores e Tipos) para procurar normalizações, como objetos e tipos relacionados.

  • Considere se ajudaria modificar temporariamente o código para isolar problemas. Por exemplo, é possível:

    • Usar Comandos do console de JavaScript para o analisador de memória, console.takeSnapshot e console.profileMark.

      É possível usar esses comandos para isolar os problemas que você não pode isolar manualmente clicando em Obter Instantâneo de Heap.

    • Criar um objeto de teste que pode ser encontrado facilmente nas exibições do JavaScript Memory Analyzer, como a Dominadores. Por exemplo, você pode anexar um objeto muito grande a outro objeto para ver se um objeto ou um elemento específico foi coletado como lixo.

  • Procure os objetos retidos acidentalmente na memória após a navegação para uma nova página, que é uma causa comum de problemas de memória. Por exemplo, o uso incorreto da função URL.CreateObjectUrl pode causar esse problema.

Consulte também

Tarefas

Tutorial: Localizando um vazamento de memória (JavaScript)