8
votes

Quelles sont la file d'attente finaliseur et le contrôle + la threadméthodentation?

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 . Super, exactement quelle est la file d'attente finaliseur? Pouvez-vous me signaler la meilleure définition? Pouvez-vous partager des conseils anecdotiques?

Aussi, tous les objets GC racine de la file d'attente de finaliser sont des instances de System.Windows.Forms.Control + Threadmethodétryry Objets nommés "Caller". Je vois que cela est impliqué dans l'interaction multi-thread de l'interface utilisateur, mais je ne sais pas beaucoup au-delà de cela. Pardonnez ma paresse apparente et a admis l'ignorance, mais ces ressources sont toutes enterrées dans les composants du vendeur. Je parle au vendeur de ces problèmes, mais j'ai besoin d'une certaine direction pour me mettre à la hauteur de la conversation. Pouvez-vous me signaler aussi la définition la plus utile de la threadméthodentation? Tout conseil anecdotique?

Aussi, devrais-je même être préoccupé par ces objets sur la file d'attente finaliseur?

mise à jour: ceci L'article de la porte rouge a été utile.


0 commentaires

3 Réponses :


1
votes

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.

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 *.


0 commentaires

19
votes

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 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>

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>

System.GC.Collect();
System.GC.WaitForPendingFinalizers(); // this method may block while it runs the finalizers
System.GC.Collect();


3 commentaires

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.



0
votes

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.


0 commentaires