quarta-feira, 2 de fevereiro de 2011

SQL Server CLR Unload e GC.Collect

Já existem diversos programadores usando o CLR (Common Language Runtime) que está hospedado dentro do SQL Server. Recentemente em um grupo de discussão apareceu um problema relacionado ao CLR e foi comentado uma maneira de se fazer o unload dos AppDomains que estão no SQL Server.

Se você utilizar o DBCC FREESYSTEMCACHE('ALL'), vai forçar o SQL Server a ativar o mecanismo de limpeza de cada cache store, e no caso do CLR vai forcar um appdomain unload.
Além do que foi citado, existe uma outra abordagem para brincar com o CLR, que é forçar a entrada do Garbage Collector, usando o DBCC FREESYSTEMCACHE('GarbageCollect'). Esse comando não é documentado, mas foi apresentado publicamente pelo Bob Ward no PASS Summit de 2008, então não vejo problema em compartilhar com vocês.

Para vermos a coisa funcionando, vamos monitorar os contadores abaixo, somente para a instância sqlservr e olhar algumas DMVs.

> .NET CLR Loading > Total appdomains unloaded
> .NET CLR Memory > #Gen0 Collections
> .NET CLR Memory > #Gen1 Collections
> .NET CLR Memory > #Gen2 Collections

select * from sys.dm_clr_appdomains
select * from sys.dm_clr_loaded_assemblies

Se você executar uma procedure que trabalha com o CLR e consultar as DMVs, verá uma entrada para o AppDomain e assemblies carregados para execução da sua rotina.
Use o comando para forçar o Garbage Collector e verá que os contadores Gen0, Gen1 e Gen2 serão acrescentados de 1, como meu procedimento é simples e não tenho nenhuma pressão na memória, me parece que é um GC.Collect(2) e não um GC.Collect(), pois a limpeza vai até a geração 2, coisa que não aconteceria em um simples collect com o CLR sem pressão na memória e espaço disponível na gen0.

Quando chamamos o procedimento que faz um AppDomain unload, vamos ver um collect até a geração 2 (provavelmente parte do processo de unload) e depois o contador de unload será acrescido de 1. Consultando logo em seguida as DMVs, verá que nada é retorando, pois o appDomain já foi removido.

Notem que não é uma boa recomendação ficar chamando o GC ou forçando o unload, ainda mais que esse irá interferir em outras cache stores, mas em casos excepcionais isso pode ser útil...


[]s
Luciano Caixeta Moreira - {Luti}
luciano.moreira@srnimbus.com.br
www.twitter.com/luticm
http://www.srnimbus.com.br/