[Só queria acrescentar mais sobre o processo de Internals of Finalization]
Portanto, você cria um objeto e, quando o objeto é coletado, o Finalize
método do objeto deve ser chamado. Mas há mais na finalização do que essa suposição muito simples.
CONCEITOS CURTOS ::
Objetos que NÃO implementam Finalize
métodos, a memória é recuperada imediatamente, a menos que, é claro, não sejam mais acessíveis pelo
código do aplicativo
Objetos implementação Finalize
método, o conceito / Implementação de Application Roots
, Finalization Queue
, Freacheable Queue
vem antes que eles possam ser recuperados.
Qualquer objeto é considerado lixo se NÃO for alcançável pelo Código do Aplicativo
Suponha: Classes / Objetos A, B, D, G, H NÃO implementam o Finalize
Método e C, E, F, I, J implementam o Finalize
Método.
Quando um aplicativo cria um novo objeto, o novo operador aloca a memória do heap. Se o tipo do objeto contiver um Finalize
método, um ponteiro para o objeto será colocado na fila de finalização .
portanto, ponteiros para os objetos C, E, F, I, J são adicionados à fila de finalização.
A fila de finalização é uma estrutura de dados interna controlada pelo coletor de lixo. Cada entrada na fila aponta para um objeto que deve ter seu Finalize
método chamado antes que a memória do objeto possa ser recuperada. A figura abaixo mostra uma pilha contendo vários objetos. Alguns desses objetos são acessíveis a partir das raízes do aplicativo, e alguns não são. Quando os objetos C, E, F, I e J foram criados, a estrutura .Net detecta que esses objetos têm Finalize
métodos e os ponteiros para esses objetos são adicionados à fila de finalização .
Quando ocorre um GC (1ª coleção), os objetos B, E, G, H, I e J são determinados como lixo. Como A, C, D, F ainda são acessíveis pelo Código do Aplicativo, representado pelas setas da Caixa amarela acima.
O coletor de lixo varre a fila de finalização procurando por ponteiros para esses objetos. Quando um ponteiro é encontrado, o ponteiro é removido da fila de finalização e anexado à fila acessível ("F alcançável").
A fila acessível é outra estrutura de dados interna controlada pelo coletor de lixo. Cada ponteiro na fila acessível identifica um objeto que está pronto para ter seu Finalize
método chamado.
Após a coleção (1ª coleção), o heap gerenciado é semelhante à figura abaixo. Explicação dada abaixo:
1.) A memória ocupada pelos objetos B, G e H foi recuperada imediatamente porque esses objetos não tinham um método finalize que precisava ser chamado .
2.) No entanto, a memória ocupada pelos objetos E, I e J não pôde ser recuperada porque seu Finalize
método ainda não foi chamado.
A chamada do método Finalize é feita por fila passível de busca.
3.) A, C, D, F ainda são acessíveis pelo Código do Aplicativo, representado pelas setas da caixa amarela acima, portanto, NÃO serão coletados em nenhum caso
Há um encadeamento de tempo de execução especial dedicado à chamada dos métodos Finalize. Quando a fila alcançável está vazia (que geralmente é o caso), esse encadeamento dorme. Mas quando as entradas aparecem, esse segmento é ativado, remove cada entrada da fila e chama o método Finalize de cada objeto. O coletor de lixo compacta a memória recuperável e o encadeamento de tempo de execução especial esvazia a fila acessível , executando o Finalize
método de cada objeto . Então aqui finalmente é quando o seu método Finalize é executado
Na próxima vez que o coletor de lixo for chamado (2ª coleção), ele verá que os objetos finalizados são realmente lixo, já que as raízes do aplicativo não apontam para ele e a fila inacessível não aponta mais para ele (também é VAZIO). A memória dos objetos (E, I, J) é simplesmente recuperada do Heap. Veja a figura abaixo e compare-a com a figura logo acima
O importante a entender aqui é que dois GCs são necessários para recuperar a memória usada por objetos que requerem finalização . Na realidade, são necessárias mais de duas cabines de coleta, pois esses objetos podem ser promovidos para uma geração mais antiga
NOTA: A fila acessível é considerada uma raiz, assim como variáveis globais e estáticas são raízes. Portanto, se um objeto estiver na fila alcançável, o objeto estará acessível e não será lixo.
Como última observação, lembre-se de que o aplicativo de depuração é uma coisa, a Coleta de Lixo é outra e funciona de maneira diferente. Até o momento, você não pode SENTIR a coleta de lixo apenas depurando aplicativos, além disso, se desejar investigar a Memória, comece aqui.