Cenário

Um aplicativo ASP.NET hospedado no IIS está apresentando esporadicamente um alto consumo de memória que não era esperado. Uma das formas de investigar o motivo deste alto consumo é analisando um dump do processo w3wp.exe (para saber mais sobre análise de dump, consulte meu outro artigo – link).

O problema neste cenário é que o “esporadicamente” dificulta que alguém da TI obtenha manualmente um dump do processo w3wp.exe no momento em que o alto consumo se apresenta.

Solução

O aplicativo DebugDiag facilita o trabalho da TI na obtenção de um dump de forma automática, podendo por exemplo, monitorar o w3wp.exe para que na ocorrência de um consumo de memória acima do normal seja gerado um dump automaticamente.

Abaixo mostro passo a passo como realizar este procedimento “agendando” a obtenção de um dump quando o consumo de memória atingir determinado patamar.

Passo a passo

1) Faça o download e instale o Debug Diagnostic Tool da Microsoft – http://www.microsoft.com/en-us/download/details.aspx?id=40336

2) Executa o aplicativo DebugDiag e adicione uma nova regra (rule)

3) Escolha a opção “Native (non-.NET) Memory and Handle Leak”

4) Escolha o processo w3wp.exe (IIS) e clique em Avançar

Observação: caso você tenha mais de uma pool no IIS você terá mais de um processo w3wp.exe no servidor, para saber o ID do processo que quer tirar o dump é possível fazê-lo de forma fácil através do comando “C:\Windows\System32\inetsrv>appcmd list wp”. Este comando irá listar o ID do processo e o nome da pool a qual ele está associado.

5)  Clique em “Configure” para especificar o monitoramento por alto consumo de memória

6)  Antes de configurar o parâmetro de memória é interessante saber os limites de consumo de memória conforme o ambiente. Neste caso, a tabela abaixo lista estes limites conforme o ambiente 32bits ou 64bits.

Process Windows Addressable memory (with a large address-aware process) Practical limit for virtual bytes Practical limit for private bytes
32-bit 32-bit 2 GB 1400 MB 800 MB
32-bit 32-bit with /3GB 3 GB 2400 MB 1800 MB
32-bit 64-bit 4 GB 3400 MB 2800 MB
64-bit 64-bit 8 TB Not applicable Not applicable

Fonte: http://www.iis.net/learn/troubleshoot/performance-issues/troubleshooting-native-memory-leak-in-an-iis-7x-application-pool

Agora sabendo dos limites de memória do seu ambiente, é necessário configurar a regra conforme o consumo de memória. Os passos a seguir descrevem esta configuração.

7) Selecione “Generate a userdump when virtual bytes reach” e defina um valor que faça sentido para o seu cenário “anormal” de consumo de memória. Por exemplo, na imagem abaixo defino que o dump seja gerado quando o processo atingir um consumo de 4GB de bytes virtuais, considerando que meu ambiente é totalmente 64-bits (processo e Windows).

8) Após configurado, clique em “Save & Close” e então em Avançar.

9) Altere os dados sugeridos caso queira e então clique em Avançar

10) Deixe a opção “Activate the rule now” selecionada e clique em Concluir.

11) A partir deste momento o DebugDiag ficará monitorando (tracking) o processo w3wp.exe.
Assim que o consumo de memória especificado for atingido ele irá obter um “dump” do processo e armazenar na pasta configurada (Userdump Path).

12) Pronto! Agora é esperar que o alto consumo de memória apareça e o dump seja gerado. A coluna Userdump Count irá mostrar a quantidade de arquivos Dump gerados.

Observações importantes

1) A regra criada no DebugDiag só vale para o ID do processo criado no momento da regra, ou seja, ocorrendo a reciclagem do IIS o DebugDiag não conseguirá monitorar o novo processo criado. Sendo assim, é necessário recriar a regra no DebugDiag. Uma alternativa é desativar a reciclagem até que se obtenha o dump.

2) Ao iniciar o monitoramento do processo, o DebugDiag injeta a LeapTrack.dll no processo w3wp.exe para que seja rastreado a alocação e liberação de memória, o que pode afetar a performance do aplicativo.

Conclusão

O dump é um importante recurso de investigação de problemas em ambiente de produção e há diversas ferramentas e técnicas para obtê-lo. A que mostrei aqui é uma destas formas, permitindo que um dump seja obtido no momento certo sem intervenção humana naquele momento. Querendo complementar ou mesmo tendo dúvidas não deixe de comentar.

Até mais!

Rafael Leonhardt
@MumHaBR

Referências

1) Debug Diagnostic 1.2 – Creating a Memory Leak rule (unmanaged code)
http://blogs.msdn.com/b/friis/archive/2012/01/04/debug-diagnostic-1-2-creating-a-memory-leak-rule-unmanaged-code.aspx

2)  Troubleshooting native memory leak in an IIS 7.x Application Pool
http://www.iis.net/learn/troubleshoot/performance-issues/troubleshooting-native-memory-leak-in-an-iis-7x-application-pool