Fujiy

Blog sobre .NET, C#, ASP.NET entre outras tecnologias de desenvolvimento de software

Value Types, Stack, Heap e confusões

30/09/2010 20:49:00 Por Fujiy

Um dos blogs que leio e com certeza é o que considero mais importante é o do Eric Lippert, inclusive traduzi uma série de artigos sobre variância e postei aqui no blog. Ele faz parte do time que desenvolve o compilador do C# e no post mais recente ele voltou a falar sobre Value Types e a confusão que normalmente ocorre, inclusive em muitos livros. Achei importe falar sobre o assunto também para o público brasileiro.

Primeiramente vamos recapitular, o que são Value Types?
...
Não, não são objetos que ficam na Stack(Pilha)! Os dois principais motivos para essa afirmação estar errada são: nem sempre os Value Types ficam na Stack; e não é essa a semântica dos Value Types.
Value Types são copiados por valor e ponto. Essa é a definição, senão ele se chamaria Stack Types certo?

Mas por que tanta confusão? O fato é que até na documentação da Microsoft diz que Value Types são alocados na Stack, mas é apenas um detalhe de implementação, na runtime distribuída pela Microsoft. Apesar disso não podemos nos basear na implementação para fazer decisões, pois teoricamente numa futura e hipotética versão do .NET pode ser que tudo fique no Heap. Claro que não vai acontecer, mas devemos ter em mente o real significado. Isso não quer dizer que distribuições de outras empresas tenham que funcionar desta forma, dependendo inclusive do SO e do hardware.

Agora por que nem sempre eles ficam na Stack? O motivo é simples, eles só ficam na Stack quando podem. Ficar na Stack tem a vantagem de ser muito mais rápido para desalocar, bastando mover um ponteiro, ao contrário do que muita gente pensa, a alocação no Heap e Stack quase sempre levam o mesmo tempo, não vou entrar em detalhes de como funciona a Stack e Heap, você pode ler mais no meu artigo sobre GC publicado na .NET Magazine.
Um Value Type pode ficar na Stack sempre que for short-lived, isto é, uma variável local que não é usada dentro de um método anônimo ou lambda e desde que o método não seja um iterator, pois nesses casos a variável é "hoisted" e acaba virando uma propriedade de uma classe gerada pelo compilador. Quando a variável é short-lived ela pode ser descartada assim que o método retornar e por isso que Reference Types não podem ficar na Stack, já que podem por exemplo serem atribuídos à uma variável global, o que não acontece com Value Types pois é sempre feito uma cópia deles na atribuição.

Nada disso é motivo pra sair criando Value Types achando que vai melhorar a performance da sua aplicação. Raramente você vai precisar criar um Value Type, e quando precisar é bom seguir algumas boas práticas, como assegurar que seu Value Type é imutável.
Value Types devem sempre representar uma única informação como um inteiro, data, etc.
Se for mal usado pode até deixar sua aplicação mais lenta.

Adicionar Comentário

Or enter your details below