.NET GARBAGE COLLECTION: Débogage vs divergence du mode de libération
Examinons le comportement de la collecte des ordures dans .NET, en nous concentrant sur les différences entre les versions de débogage et de libération. Considérez cet exemple C #:
public class Class1 { public static int c; ~Class1() { c++; } } public class Class2 { public static void Main() { { var c1 = new Class1(); //c1 = null; // Uncommenting this results in "1" at the Console.WriteLine call. } GC.Collect(); GC.WaitForPendingFinalizers(); Console.WriteLine(Class1.c); // Outputs "0" Console.Read(); } }
L'exécution de ce code pourrait produire un résultat surprenant: Class1.c
reste 0, même si c1
est hors de portée et apparemment éligible à la collecte des ordures.
Le mécanisme sous-jacent
L'écart découle des optimisations du compilateur JIT. En mode version, le compilateur optimise le code des performances, créant souvent des tables pour suivre l'utilisation des variables. Cela permet une collection de déchets efficace.
Cependant, en mode débogage, ces optimisations sont désactivées pour faciliter le débogage. Le temps d'exécution maintient des références aux variables locales plus longtemps que strictement nécessaires, prolongeant efficacement leur durée de vie jusqu'à la fin de la méthode.
Dans notre exemple, le débogueur garde une référence à c1
tout au long de Main()
, empêchant sa finalisation immédiate. Par conséquent, la sortie est "0," pas "1."
Implications de production et meilleures pratiques
Cette différence est cruciale. Le comportement du mode de libération diffère considérablement du mode de débogage. Ne comptez jamais sur un calendrier spécifique de la collecte des ordures dans votre code, en particulier en mode débogage. Évitez la finalisation de l'objet manuel ou les affectations nuls pour contrôler la collecte des ordures. Laissez la mémoire d'exécution gérer la mémoire.
Considérations clés:
GC.KeepAlive()
: Utilisez cette méthode pour empêcher explicitement la collecte des ordures d'objets spécifiques si vous êtes absolument nécessaire (par exemple, interoppez avec du code non géré). GC.KeepAlive()
garantit que les objets restent accessibles jusqu'à ce que le code non géré se termine en les utilisant. Marshal.ReleaseComObject()
. Au lieu de cela, comptez sur le collecteur des ordures pour le nettoyage des objets com. Cette explication clarifie pourquoi les objets apparemment collectés pourraient persister en mode débogage, soulignant l'importance des tests en mode de libération pour un comportement précis de collecte des ordures.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!