Conceitos sobre a criação de perfil

Nesta página, você encontra uma visão geral sobre a criação de perfis, os tipos disponíveis no Stackdriver Profiler e informações sobre eles.

O que é criação de perfil?

A criação de perfil é uma análise de códigos dinâmica. Ou seja, é possível coletar as características do código durante a execução dele (por isso é dinâmico). Você consegue examinar o consumo real de recursos ou as características de desempenho do programa.

Ao criar o perfil e fazer o teste do seu código durante o desenvolvimento, é possível otimizar o design dele e encontrar bugs. Isso reduz o risco de falhas na produção.

Criar o perfil do código de produção ajuda a prever quando futuros problemas poderão surgir e a diagnosticar os que ocorrerem.

A criação de perfil gera uma carga complementar no programa durante a coleta de estatísticas sobre o código em execução. Isso é diferente da análise de código estático, que examina o código-fonte do aplicativo em vez do aplicativo executado. Além disso, é necessário que a criação de perfil seja capaz de coletar e recuperar essas estatísticas a partir do ambiente de execução. Essa tarefa extra gera carga no programa.

Há muitas maneiras de coletar dados de criação de perfil e várias formas de reduzir a carga complementar gerada no aplicativo executado. Isso normalmente inclui equilibrar a precisão das características com o perfil criado e os obstáculos no aplicativo em execução.

Stackdriver Profiler

O Stackdriver Profiler é um criador de perfil estatístico ou de amostragem. Ele não requer que você faça alterações abrangentes no código do programa para coletar dados. Na verdade, um trecho de código chamado de agente de criação de perfil é anexado por padrão. Ele examina periodicamente a pilha de chamadas do programa para coletar informações como o uso da CPU ou da memória.

Normalmente, os criadores de perfil de amostragem são menos precisos porque eles analisam as características desse processo. No entanto, eles têm um impacto mínimo no desempenho do aplicativo com perfil criado, o que é particularmente importante na criação contínua de perfil do código de produção. A precisão melhora à medida que o número de amostras é aprimorado, mesmo que isso seja uma aproximação estatística.

Para informações sobre como executar o agente Stackdriver Profiler com seu aplicativo, consulte as páginas a seguir:

Depois de coletar dados do criador de perfil, faça a análise deles usando a interface do Profiler.

Tipos de criação de perfil disponíveis

O Stackdriver Profiler é compatível com diferentes tipos de criação de perfil com base na linguagem em que o programa é gravado. A tabela a seguir resume os tipos compatíveis por linguagem:

Tipo de perfil Go Java Node.js Python
Tempo de CPU SS S
Heap SS S
Heap alocada S
Contenção S
Linhas de execução S
Tempo decorrido S SS

Medição de tempo

  • Tempo de CPU é o tempo que a CPU gasta executando um bloco de código.

  • Tempo decorrido é o tempo que leva para executar um bloco de código.

O tempo de CPU de uma função mostra quanto tempo foi necessário para executar o código nela. Isso mede quanto tempo a CPU gastou processando as instruções. Ele não inclui o tempo que a CPU estava esperando ou processando instruções de algo diferente.

O tempo decorrido de uma função é referente ao momento entre a entrada e a saída dela. Isso inclui o tempo de espera por bloqueios no acesso ao banco de dados, pela sincronização de linhas de execução, pelos bloqueios e assim por diante. O tempo decorrido de um bloco de código nunca pode ser menor que o da CPU.

Um bloco de código pode levar muito tempo para ser executado. No entanto, ele requer pouco tempo de CPU. Se o tempo decorrido for muito maior que o da CPU, o código levará muito tempo esperando que outras atividades aconteçam. Isso indica um gargalo de recursos, em que muitos solicitantes tentam acessar algum recurso limitado.

Se o tempo de CPU estiver próximo do decorrido, o bloco de código é de uso intensivo da CPU: quase todo o tempo que leva para ele ser executado é gasto pela CPU. Recomendamos a otimização dos blocos de código de longa duração com uso intensivo da CPU: há uma maneira mais eficiente de usar a CPU para realizar o trabalho? Algo que envolva operações mais rápidas ou em quantidades menores?

Consumo de heap (memória)

  • O consumo de heap (também chamado de heap) é a quantidade de memória alocada no heap do programa quando o perfil é coletado.

  • Alocação de heap (também chamada de heap alocada) é a quantidade total de memória que foi alocada no heap do programa, incluindo a memória liberada e não mais em uso.

Conforme os programas são executados, eles consomem memória, criam objetos e chamam funções. Tudo isso ocupa espaço.

Um programa com bom funcionamento usa a memória com eficiência e cuidado. Ele utiliza apenas a memória necessária, ou seja, não consome recursos excessivos. Ele também devolve essa memória quando não precisa mais dela. Assim, não há vazamentos.

Quando um programa consome mais memória do que precisa ou usa uma quantidade não mais necessária, ele é iniciado lentamente, tem o desempenho reduzido gradualmente ou falha. Isso pode até afetar os recursos disponíveis para outros aplicativos. Um programa que aloca memória com mais frequência do que o necessário em uma linguagem de coleta de lixo gera mais trabalho para o coletor.

Ao criar o perfil do consumo de heap, você encontra possíveis ineficiências e vazamentos de memória nos programas. Com criação de perfis de alocações de heap, é possível saber quais delas estão gerando mais trabalho para o coletor de lixo.

Informações sobre linhas de execução

Os aplicativos que criam linhas de execução podem ter alguns problemas, como linhas bloqueadas, outras que são criadas, mas nunca executadas e vazamentos em que o número de linhas de execução criadas continua aumentando. O primeiro problema é uma das causas do segundo.

Contenção

Em um programa de várias linhas de execução, o tempo gasto na espera para serializar o acesso a um recurso compartilhado pode ser grande. Entender o comportamento da contenção orienta o design do código e fornece informações para fazer ajustes no desempenho.

Coleta de perfis

Para usar o Stackdriver Profiler com seu serviço, para todas as linguagens, exceto Java, é necessário modificar o serviço para instanciar um agente de criação de perfil quando o serviço for iniciado. Para aplicativos Java, é preciso modificar a maneira como você inicia o serviço. Para cada instância do aplicativo, um agente de criação de perfil é instanciado.

O papel de um agente é capturar dados de perfil de seu serviço e transmiti-los para o back-end do Profiler usando a API Profiler. Cada perfil é para uma única instância de um serviço e inclui quatro campos que identificam a implantação:

  • Projeto do GCP
  • Nome do serviço
  • Zona de serviço
  • Versão de serviço

Quando um agente está pronto para capturar um perfil, ele emite um comando da API Profiler para o back-end do Profiler. O back-end recebe essa solicitação e, no cenário mais simples, responde imediatamente ao agente. A resposta especifica o tipo de perfil a ser capturado. Em resposta, o agente captura o perfil e o transmite para o back-end. Por fim, o back-end do Profiler associa o perfil ao seu projeto GCP. É possível visualizá-lo e analisá-lo usando a IU do Profiler.

A sequência real de handshake é mais complexa do que a descrita no parágrafo anterior. Por exemplo, quando o Profiler recebe uma solicitação de um agente que está pronto para coletar um perfil, o back-end verifica o banco de dados dele para determinar se ele recebeu solicitações anteriores do agente. Caso contrário, o back-end adicionará as informações do agente ao banco de dados. Uma nova implantação será criada se os campos de implantação do agente não corresponderem aos de qualquer outro agente registrado.

A cada minuto, em média, e para cada implantação e cada tipo de perfil, o back-end seleciona um agente e o instrui a capturar um perfil. Por exemplo, se os agentes de uma implantação forem compatíveis com a criação de perfil de tempo decorrido e de heap, em média, dois perfis serão capturados por minuto:

  • Para todos os tipos de perfil, exceto o consumo de heap e o consumo de linhas de execução, um único perfil representa os dados coletados por 10 segundos.

  • Para os perfis de linha de execução e consumo de heap, cada perfil é coletado instantaneamente.

É importante observar que, depois que o agente notifica o back-end do Profiler para capturar dados, ele fica ocioso até receber uma resposta do back-end que especifica o tipo de perfil a ser capturado. Se você tiver 10 instâncias de um serviço em execução na mesma implantação, crie 10 agentes de criação de perfil. No entanto, na maioria das vezes, esses agentes ficam inativos. Em um período de 10 minutos, são esperados 10 perfis. Cada agente recebe uma resposta para cada tipo de perfil, em média. Há uma ordem aleatória envolvida, então o número real pode variar.

O back-end do Profiler usa as cotas da API Profiler e os campos de implantação do perfil para limitar os perfis processados. Para informações sobre como visualizar e gerenciar suas cotas do Profiler, consulte Cotas e limites.