Monitoramento de recursos do domínio do aplicativo

O monitoramento de recursos do domínio do aplicativo (ARM) permite que os hosts monitorem o uso da CPU e da memória por domínio do aplicativo. Isso é útil para hosts como ASP.NET que usam muitos domínios de aplicativo em um processo de longa execução. O host pode descarregar o domínio do aplicativo de um aplicativo que está afetando negativamente o desempenho de todo o processo, mas somente se puder identificar o aplicativo problemático. O ARM fornece informações que podem ser usadas para ajudar na tomada de tais decisões.

Por exemplo, um serviço de hospedagem pode ter muitos aplicativos em execução em um servidor ASP.NET. Se um aplicativo no processo começar a consumir muita memória ou muito tempo do processador, o serviço de hospedagem pode usar o ARM para identificar o domínio do aplicativo que está causando o problema.

O ARM é suficientemente leve para ser usado em aplicações ao vivo. Você pode acessar as informações usando o rastreamento de eventos para Windows (ETW) ou diretamente por meio de APIs gerenciadas ou nativas.

Habilitando o monitoramento de recursos

O ARM pode ser habilitado de quatro maneiras: fornecendo um arquivo de configuração quando o Common Language Runtime (CLR) é iniciado, usando uma API de hospedagem não gerenciada, usando código gerenciado ou ouvindo eventos ARM ETW.

Assim que o ARM é habilitado, ele começa a coletar dados em todos os domínios de aplicativo no processo. Se um domínio de aplicativo tiver sido criado antes de o ARM ser habilitado, os dados cumulativos serão iniciados quando o ARM estiver habilitado, não quando o domínio do aplicativo for criado. Uma vez ativado, o ARM não pode ser desativado.

  • Você pode habilitar o ARM na inicialização do CLR adicionando o <elemento appDomainResourceMonitoring> ao arquivo de configuração e definindo o enabled atributo como true. Um valor de (o padrão) significa apenas que o ARM não está habilitado false na inicialização, você pode ativá-lo mais tarde usando um dos outros mecanismos de ativação.

  • O host pode habilitar o ARM solicitando a interface de hospedagem ICLRAppDomainResourceMonitor . Uma vez que esta interface é obtida com sucesso, o ARM é ativado.

  • O código gerenciado pode habilitar o ARM definindo a propriedade static (Shared no Visual Basic) AppDomain.MonitoringIsEnabled como true. Assim que a propriedade é definida, o ARM é ativado.

  • Você pode habilitar o ARM após a inicialização ouvindo eventos ETW. O ARM é habilitado e começa a gerar eventos para todos os domínios de aplicativo quando você habilita o provedor Microsoft-Windows-DotNETRuntime público usando a AppDomainResourceManagementKeyword palavra-chave. Para correlacionar dados com domínios de aplicativo e threads, você também deve habilitar o Microsoft-Windows-DotNETRuntimeRundown provedor com a ThreadingKeyword palavra-chave.

Usando ARM

O ARM fornece o tempo total do processador usado por um domínio de aplicativo e três tipos de informações sobre o uso da memória.

  • Tempo total do processador para um domínio de aplicativo, em segundos: isso é calculado somando os tempos de thread relatados pelo sistema operacional para todos os threads que gastaram tempo de execução no domínio do aplicativo durante sua vida útil. Threads bloqueados ou em suspensão não usam o tempo do processador. Quando um thread chama o código nativo, o tempo que o thread gasta no código nativo é incluído na contagem do domínio do aplicativo onde a chamada foi feita.

  • Total de alocações gerenciadas feitas por um domínio de aplicativo durante seu tempo de vida, em bytes: As alocações totais nem sempre refletem o uso de memória por um domínio de aplicativo, porque os objetos alocados podem ter vida curta. No entanto, se um aplicativo aloca e libera um grande número de objetos, o custo das alocações pode ser significativo.

  • Memória gerenciada, em bytes, que é referenciada por um domínio de aplicativo e que sobreviveu à coleção completa de bloqueio mais recente: esse número é preciso somente após uma coleção completa de bloqueio. (Isso contrasta com coleções simultâneas, que ocorrem em segundo plano e não bloqueiam o aplicativo.) Por exemplo, a sobrecarga do GC.Collect() método causa uma coleção completa e bloqueada.

  • Total de memória gerenciada, em bytes, que é referenciada pelo processo e que sobreviveu à coleção completa de bloqueio mais recente: A memória sobrevivente para domínios de aplicativos individuais pode ser comparada a esse número.

Determinando quando ocorre uma coleção completa e bloqueada

Para determinar quando as contagens de memória sobrevivente são precisas, você precisa saber quando uma coleção completa e bloqueada acabou de ocorrer. O método para fazer isso depende da API que você usa para examinar as estatísticas ARM.

API gerenciada

Se você usar as propriedades da AppDomain classe, poderá usar o GC.RegisterForFullGCNotification método para registrar para notificação de coleções completas. O limite que você usa não é importante, porque você está aguardando a conclusão de uma coleção em vez da abordagem de uma coleção. Em seguida, você pode chamar o GC.WaitForFullGCComplete método, que bloqueia até que uma coleção completa seja concluída. Você pode criar um thread que chama o método em um loop e faz qualquer análise necessária sempre que o método retorna.

Como alternativa, você pode chamar o GC.CollectionCount método periodicamente para ver se a contagem de coleções de geração 2 aumentou. Dependendo da frequência de sondagem, esta técnica pode não fornecer uma indicação tão precisa da ocorrência de uma recolha completa.

API de hospedagem

Se você usar a API de hospedagem não gerenciada, seu host deverá passar ao CLR uma implementação da interface IHostGCManager . O CLR chama o método IHostGCManager::SuspensionEnding quando retoma a execução de threads que foram suspensos enquanto ocorre uma coleção. O CLR passa a geração da coleção concluída como um parâmetro do método, para que o host possa determinar se a coleção foi completa ou parcial. Sua implementação do método IHostGCManager::SuspensionEnding pode consultar a memória sobrevivente, para garantir que as contagens sejam recuperadas assim que forem atualizadas.

Consulte também