Considere o seguinte programa C #, eu o enviei no codegolf como uma resposta para criar um loop sem loop:
class P{
static int x=0;
~P(){
System.Console.WriteLine(++x);
new P();
}
static void Main(){
new P();
}
}
Este programa parece um loop infinito em minha inspeção, mas parece ser executado por vários milhares de iterações e, em seguida, o programa é encerrado com êxito sem erros (nenhum erro é gerado). É uma violação de especificação para a qual o finalizador P
eventualmente não é chamado?
Claramente, este é um código estúpido, que nunca deveria aparecer, mas estou curioso para saber como o programa poderia ser concluído.
Código original da postagem de golfe :: /codegolf/33196/loop-without-looping/33218#33218
c#
garbage-collection
Michael B
fonte
fonte
Respostas:
De acordo com Richter na segunda edição do CLR via C # (sim, preciso atualizar):
Página 478
Além disso, como Servy menciona, ele tem seu próprio segmento.
fonte
O finalizador não é executado no thread principal. O finalizador tem seu próprio thread que executa o código, e não é um thread de primeiro plano que manteria o aplicativo em execução. O encadeamento principal é concluído com eficácia imediatamente, momento em que o encadeamento finalizador simplesmente é executado quantas vezes puder antes que o processo seja interrompido. Nada está mantendo o programa vivo.
fonte
Um coletor de lixo não é um sistema ativo. Ele funciona "às vezes" e principalmente sob demanda (por exemplo, quando todas as páginas oferecidas pelo sistema operacional estão cheias).
A maioria dos coletores de lixo é executada de maneira semelhante à da primeira geração em um subtread. Na maioria dos casos, pode levar horas até que o objeto seja reciclado.
O único problema ocorre quando você deseja encerrar o programa. No entanto, isso não é realmente um problema. Quando você usa
kill
um sistema operacional irá pedir educadamente para encerrar processos. Quando o processo, no entanto, permanece ativo, pode-se usarkill -9
onde o sistema operacional remove todo o controle.Quando executei seu código no
csharp
ambiente interativo , obtive:Portanto, seu programa trava porque
stdout
está bloqueado pela terminação do ambiente.Ao remover
Console.WriteLine
e matar o programa. Depois de cinco segundos, o programa termina (em outras palavras, o coletor de lixo desiste e simplesmente vai liberar toda a memória sem levar os finalizadores em consideração).fonte
P
instância simplesmente expirou.