.NET Core - coleta de lixo
Neste capítulo, abordaremos o conceito de Coleta de lixo, um dos recursos mais importantes da plataforma de código gerenciado .NET. O coletor de lixo (GC) gerencia a alocação e a liberação de memória. O coletor de lixo funciona como um gerenciador automático de memória.
Você não precisa saber como alocar e liberar memória ou gerenciar o tempo de vida dos objetos que usam essa memória
Uma alocação é feita sempre que você declara um objeto com uma palavra-chave “nova” ou um tipo de valor está em uma caixa. As alocações são normalmente muito rápidas
Quando não há memória suficiente para alocar um objeto, o GC deve coletar e descartar a memória de lixo para disponibilizar memória para novas alocações.
Este processo é conhecido como garbage collection.
Vantagens da coleta de lixo
A coleta de lixo oferece os seguintes benefícios -
Você não precisa liberar memória manualmente ao desenvolver seu aplicativo.
Ele também aloca objetos no heap gerenciado com eficiência.
Quando os objetos não são mais usados, ele recupera esses objetos limpando sua memória e mantém a memória disponível para futuras alocações.
Os objetos gerenciados obtêm conteúdo limpo para começar, de forma que seus construtores não tenham que inicializar todos os campos de dados.
Ele também fornece segurança de memória, garantindo que um objeto não possa usar o conteúdo de outro objeto.
Condições para coleta de lixo
A coleta de lixo ocorre quando uma das seguintes condições for verdadeira.
O sistema está com pouca memória física.
A memória usada por objetos alocados no heap gerenciado ultrapassa um limite aceitável. Este limite é continuamente ajustado conforme o processo é executado.
o GC.Collectmétodo é chamado e, em quase todos os casos, você não precisa chamar esse método, porque o coletor de lixo é executado continuamente. Este método é usado principalmente para situações e testes únicos.
Gerações
O .NET Garbage Collector tem 3 gerações e cada geração possui seu próprio heap que é usado para o armazenamento de objetos alocados. Existe um princípio básico de que a maioria dos objetos tem vida curta ou longa.
Primeira geração (0)
Na Geração 0, os objetos são alocados primeiro.
Nesta geração, os objetos geralmente não vivem além da primeira geração, uma vez que não estão mais em uso (fora do escopo) no momento em que ocorre a próxima coleta de lixo.
A geração 0 é rápida de coletar porque seu heap associado é pequeno.
Segunda geração (1)
Na Geração 1, os objetos têm um espaço de segunda chance.
Objetos que têm vida curta, mas sobrevivem à coleção da geração 0 (muitas vezes com base no tempo coincidente) vão para a geração 1.
As coleções da geração 1 também são rápidas porque seu heap associado também é pequeno.
Os dois primeiros heaps permanecem pequenos porque os objetos são coletados ou promovidos para o heap da próxima geração.
Terceira geração (2)
Na geração 2, todos os objetos longos são vividos e sua pilha pode crescer muito.
Os objetos nesta geração podem sobreviver por muito tempo e não há heap da próxima geração para promover ainda mais os objetos.
O Garbage Collector possui um heap adicional para objetos grandes, conhecido como Large Object Heap (LOH).
É reservado para objetos com 85.000 bytes ou mais.
Objetos grandes não são alocados para os heaps de geração, mas são alocados diretamente para o LOH
As coleções da Geração 2 e LOH podem levar um tempo notável para programas que foram executados por muito tempo ou operam com grandes quantidades de dados.
Sabe-se que programas de servidor grandes têm pilhas na casa dos 10 GBs.
O GC emprega uma variedade de técnicas para reduzir a quantidade de tempo que bloqueia a execução do programa.
A abordagem principal é fazer o máximo possível de trabalho de coleta de lixo em um thread de segundo plano de uma maneira que não interfira na execução do programa.
O GC também expõe algumas maneiras para os desenvolvedores influenciarem seu comportamento, o que pode ser bastante útil para melhorar o desempenho.