J'ai une application Windowsforms qui semble fuir la mémoire, j'ai donc utilisé le profileur de mémoire des fourmis de RedGate pour regarder les objets que je soupçonne et constater qu'ils ne sont détenus que par des objets déjà sur la queue de finaliseur forte>. Super, exactement quelle est la file d'attente finaliseur? Pouvez-vous me signaler la meilleure définition? Pouvez-vous partager des conseils anecdotiques? P>
Aussi, tous les objets GC racine de la file d'attente de finaliser sont des instances de Aussi, devrais-je même être préoccupé par ces objets sur la file d'attente finaliseur? p>
3 Réponses :
La file d'attente finaliseur est une file d'attente où les instances d'objet qui ne sont plus utilisées attendent d'être finalisées par le GC. Tous les objets de cette file d'attente seront finalisés et vos fuites de mémoire ne proviennent probablement pas d'une de elles directement. Mais, l'un de ces objets peut ne pas libérer toutes ses ressources non gérées. P>
La classe ThreadMethodEntryry est une implémentation d'iAsyncResultsulte et des instances de cette classe sont généralement créées lors de l'appel d'opérations asynchrones, telles que l'utilisation d'invoquer pour mettre à jour l'interface utilisateur ou l'utilisation des méthodes de début * / fin *. P>
La file d'attente du finaliseur contient tous les objets qui ont une méthode de finaliseur définie. Rappelez-vous qu'un finaliseur est un moyen de collecter des ressources non gérées comme des poignées. Lorsque le collecteur des ordures collecte des ordures, il déplace tous les objets avec un finaliseur dans la file d'attente finaliseur. À un moment donné, plus tard - en fonction de la pression de la mémoire, de la heuristique GC et de la phase de la lune-- lorsque le collecteur des ordures décide de collecter ces objets, il descend la file d'attente et exécute les finaliseurs.
Ayant travaillé avec des fuites de mémoire Dans le passé, voyant un groupe d'objets de votre fournisseur dans la file d'attente de finaliser pourrait être du code bâclé, mais cela n'indique pas une fuite de mémoire. En règle générale, un bon code exposera une méthode d'élimination qui collectera les ressources gérées et non gérées, et ce faisant, de le supprimer de la file d'attente finaliseur via Avez-vous essayé de créer un instantané dans des fourmis entre deux points à temps et comparer les objets créés entre eux? Cela peut vous aider à identifier tous les objets gérés. P> En outre, si vous souhaitez voir si la mémoire disparaît lorsque les derniers sont exécutés, essayez-le simplement de tester avec: P> gc.suppressfinalize () code>. Donc, si les objets du fournisseur mettent en œuvre une méthode de jet et votre code ne l'appelle pas, cela pourrait conduire à un groupe d'objets dans la file d'attente finaliseur. P>
System.GC.Collect();
System.GC.WaitForPendingFinalizers(); // this method may block while it runs the finalizers
System.GC.Collect();
Merci pour la grande réponse, Paul. C'est le graphique de référence d'objet dont je parle, en regardant de nouveaux objets dans le deuxième instantané, après la nettoyage des ressources. Tous les objets du graphique qui implémentent Idisposable ont un embout d'outil indiquant "Dispose () a été appelé à cet objet" mais l'objet sélectionné n'a pas de telle info-bulle.
Note sur ThreadMethodétry: Je pense qu'ils sont utilisés dans n'importe quel invoke sur le fil de l'interface utilisateur. Chaque objet de contrôle a une file d'attente de rappel de fil de type threhododétry. Un racyclate décide d'une threadméthodentation et de la gère. Chaque objet threadméthodenterie a un tas de champs internes. L'examen de ces champs pourrait vous aider à déterminer lequel des objets de ces fournisseurs invoquent. Je ne me souviens pas si vous pouvez obtenir cette information des fourmis, mais je sais que vous pouvez via wingbg.dll et sos.dll (extensions de débogueur gérées). Regardez la "méthode" déléguée et le contrôle "appelant".
Notez également que les objets ThreadMethodétryRytry mettent en place un finisseur, mais ils n'ont pas de méthode de jetter. Lorsqu'ils terminent, ils seraient déplacés vers la file d'attente du finisseur.
Voici un bon livre de blog décrit un problème similaire. À un niveau plus technique, vous pouvez rechercher à l'aide de SOS.DLL (que le blog post décrit) et sentex.dll pour vous aider à déterminer pourquoi ces objets de threadméthodétrie sont suspendus dans la mémoire. Il existe des commandes dans ces extensions Windbg qui peuvent suivre ce que les autres objets référencent un objet spécifique en mémoire. P>