Considérez le programme C # suivant, je l'ai soumis sur codegolf comme réponse pour créer une boucle sans boucle:
class P{
static int x=0;
~P(){
System.Console.WriteLine(++x);
new P();
}
static void Main(){
new P();
}
}
Ce programme ressemble à une boucle infinie dans mon inspection, mais il semble fonctionner pendant plusieurs milliers d'itérations, puis le programme se termine avec succès sans erreur (aucune erreur n'est générée). Est-ce une violation de spécification pour laquelle le finaliseur P
n'est finalement pas appelé?
Il s'agit clairement d'un code stupide, qui ne devrait jamais apparaître, mais je suis curieux de savoir comment le programme pourrait se terminer.
Code de poste de golf d'origine :: /codegolf/33196/loop-without-looping/33218#33218
c#
garbage-collection
Michael B
la source
la source
Réponses:
Selon Richter dans la deuxième édition de CLR via C # (oui, je dois mettre à jour):
Épisode 478
De plus, comme le mentionne Servy, il a son propre fil.
la source
Le finaliseur ne s'exécute pas dans le thread principal. Le finaliseur a son propre thread qui exécute le code, et ce n'est pas un thread de premier plan qui permettrait à l'application de continuer à fonctionner. Le thread principal se termine efficacement immédiatement, à quel point le thread du finaliseur s'exécute simplement autant de fois qu'il le peut avant que le processus ne soit interrompu. Rien ne maintient le programme en vie.
la source
Un garbage collector n'est pas un système actif. Il s'exécute «parfois» et principalement à la demande (par exemple lorsque toutes les pages proposées par l'OS sont pleines).
La plupart des garbage collector s'exécutent à la manière de la première génération dans un sous-thread. Dans la plupart des cas, le recyclage de l'objet peut prendre des heures.
Le seul problème se produit lorsque vous souhaitez mettre fin au programme. Cependant, ce n'est pas vraiment un problème. Lorsque vous utilisez
kill
un système d'exploitation, vous demanderez poliment de mettre fin aux processus. Lorsque le processus reste cependant actif, on peut utiliserkill -9
là où le système d'exploitation supprime tout contrôle.Lorsque j'ai exécuté votre code dans l'
csharp
environnement interactif , j'ai:Ainsi , votre programme se bloque à cause
stdout
est bloqué par le termintation de l'environnement.Lors de la suppression
Console.WriteLine
et de la suppression du programme. Au bout de cinq secondes, le programme se termine (en d'autres termes, le ramasse-miettes abandonne et libère simplement toute la mémoire sans prendre en compte les finaliseurs).la source
P
instance a simplement expiré.