Question

J'ai une application WindowsForms qui semble fuir la mémoire, donc je ANTS Profiler mémoire de Redgate à regarder les objets que je suspect et constater qu'ils ne sont détenus par des objets déjà sur la Finalizer Queue . Grand, exactement ce qui est un Finalizer file d'attente? Pouvez-vous me montrer à la meilleure définition? Pouvez-vous partager des conseils anecdotiques?

En outre, tous les objets GC racine sur la file d'attente Finalizer sont des instances de System.Windows.Forms.Control + ThreadMethodEntry objets nommés "appelant". Je vois qu'il est impliqué dans l'interaction de l'interface utilisateur multi-thread, mais je ne sais pas grand-chose au-delà. Pardonnez ma paresse apparente et de l'ignorance admise, mais ces ressources sont enterrés au sein de la composante d'un fournisseur. Je parle au vendeur de ces questions, mais je dois une certaine direction pour me mettre à jour sur la conversation. Pouvez-vous me montrer à la définition la plus utile de ThreadMethodEntry aussi? Un conseil anecdotique?

Aussi, dois-je encore préoccupé par ces objets sur la file d'attente de finaliseur?

Mise à jour: Ce article Red Gate utile.

Était-ce utile?

La solution

La file d'attente de finalisation contient tous les objets qui ont une méthode de finaliseur défini. Rappelons qu'un finaliseur est un moyen de collecter des ressources non gérés comme les poignées. Lorsque le collecteur d'ordures collecte des ordures, il se déplace tout objet avec un finaliseur dans la file d'attente de finalisation. À un certain moment en fonction de la pression later-- mémoire, heuristiques GC, et la phase du moon-- lorsque le garbage collector décide de collecter ces objets, il marche dans la file d'attente et exécute les finaliseurs.

Après avoir travaillé avec des fuites de mémoire dans le passé, voir un tas de objets de votre fournisseur dans la file d'attente de finaliseur peut être le code bâclé, mais il n'indique pas une fuite de mémoire. En règle générale, un bon code exposera une méthode Dispose qui permettra de recueillir les ressources gérées et non gérées, et ce faisant, se retirer de la file d'attente via finaliseur GC.SuppressFinalize(). Donc, si les objets du fournisseur faire mettre en œuvre une méthode Dispose et votre code ne remet pas, cela pourrait conduire à un tas d'objets dans la file d'attente de finaliseur.

Avez-vous essayé de créer un instantané dans ANTS entre deux points dans le temps et la comparaison des objets créés entre eux? Cela peut vous aider à identifier les objets gérés sont divulgués.

En outre, si vous voulez voir si la mémoire disparaît lorsque les finaliseurs sont exécutés, essayez ceci juste pour tester avec:

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

Je ne recommande pas d'exécuter ce code normalement. Vous pouvez l'exécuter si vous venez de faire une tonne de travail et créé beaucoup de déchets. Par exemple, dans notre application, l'une de nos fonctions peuvent créer environ 350 Mo d'ordures qui va perdre après la fermeture d'une fenêtre MDI. Comme il est connu pour laisser beaucoup d'ordures, nous forcer manuellement la collecte des ordures.

Notez également qu'il ya un cache de propriétés de bas niveau dans le code de base Windows.Forms qui tiendra à la dernière ouverture de dialogue modale. Cela pourrait être une source d'une fuite de mémoire. Un moyen sûr de se débarrasser de cette référence est de forcer une autre boîte de dialogue simple à apparaître, puis exécutez le code GC ci-dessus.

Autres conseils

La file d'attente est finaliseur une file d'attente où les instances d'objets qui ne sont plus utilisés sont en attente d'être finalisé par le GC. Tous les objets de cette file d'attente seront finalisés et vos fuites de mémoire ne sont probablement pas d'un de ceux-ci directement. Mais, l'un de ces objets ne peut pas libérer toutes ses ressources non gérés.

La classe ThreadMethodEntry est une mise en oeuvre de IAsyncResult et instances de cette classe sont généralement créés lors de l'appel des opérations asynchrones, comme l'utilisation de Invoke pour mettre à jour l'interface utilisateur ou en utilisant Begin * / Fin * méthodes.

Sosex.dll pour vous aider à comprendre pourquoi ces objets ThreadMethodEntry sont suspendus autour de la mémoire. Il existe des commandes dans ces extensions WinDBg qui peuvent traquer ce que les autres objets font référence à un objet spécifique dans la mémoire.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top