2010-11-13 10 views
4

J'utilise une boucle for pour générer certaines commandes. Chaque contrôle présente une visualisation spéciale. Je ne peux pas utiliser des contrôles comme ListBox ou quelque chose comme ça. Je dois utiliser mon approche. Les contrôles générés sont hébergés dans un canevas. Après un certain temps, certains contrôles ne sont plus nécessaires. Certains contrôles doivent être supprimés. Je peux supprimer manuellement un contrôle viaDétruire les contrôles

c.Children.Remove(...); 

cette ligne. Comment puis-je déterminer que les contrôles ont vraiment été collectés à partir de la collecte des ordures? Peut-être que le contrôle existe déjà dans la mémoire ... Comment puis-je m'assurer de cela?

Le problème est que je génère des données en tonnes!

Merci d'avance! :-)

Répondre

1

Tant que rien ne contient de référence à un contrôle, le garbage collector s'en débarrasse et vous n'avez plus à vous soucier de rien. Habituellement, en supprimant un contrôle de la collection qui contient tout ce que vous devez faire. Mais vous devez faire attention avec les gestionnaires d'événements. Si l'objet A s'abonne à un événement que l'objet B déclenche, l'objet B contient une référence à l'objet A. Si vos contrôles s'abonnent, par exemple, Canvas.IsEnabledChanged, vous pouvez les supprimer du Canvas, mais le Canvas contiendra toujours une référence à eux. qu'il peut les notifier quand IsEnabled change, et ils ne seront pas ramassés. C'est la cause la plus fréquente de "fuites de mémoire" dans les applications .NET. (Ils ne sont pas vraiment des fuites de mémoire, mais ils pourraient aussi bien être.)

4

Donc, si vous appelez le contrôle, et que vous n'avez pas maintenu d'autres références au contrôle en mémoire (comme dans une table de hachage de contrôles ou quelque chose), le GC le recueillera. N'essayez pas de forcer le .NET GC à faire quelque chose de fantaisie, laissez-le faire son travail dans son temps comme l'ont conçu les auteurs de la bibliothèque. Si vous Destroy il, il sera parti, en temps voulu. Enfin, si vous pensez que cela continue de consommer de la mémoire, il est temps de commencer à profiler votre code, comme par exemple avec RedGate Ants.

+0

Il semble que l'OP utilise WPF (qui n'a pas de méthode 'Dispose()' sur les contrôles) au lieu de Winforms. –

+0

@ZachJohnson ~ Oh merde, vous avez raison.Quoi qu'il en soit, le reste de mon code, à côté des commentaires spécifiques 'Destroy', est toujours synonyme de WPF, non? Mais oui, System.Object ne définit que pour l'héritage 'Finalize', et non' Destroy' ... cependant, un objet individuel _could_ hérite 'IDisposable' ou possède une méthode' Dispose' (bien que celle-ci n'en ait pas) effet) – jcolebrand

2

Vous n'en avez pas vraiment besoin. C'est le sens de la collecte des ordures: dès qu'il y a trop d'objets morts, la collecte des ordures saute dedans et les nettoie. Ou ne nettoie pas: le GC sait mieux quoi et quand le retirer.

4

Selon le contrôle que vous utilisez peut-être vous devez appeler Control.Dispose() pour libérer toutes les ressources. Soyez prudent si vous utilisez des ressources non gérées (Learn more)

Je pense que ce n'est pas votre cas.

Ensuite, le garbage collector recueillera l'objet pour vous.

En outre, cet article sur la façon dont fonctionne Garbage Collector pourrait être très intéressant:

http://www.codeproject.com/KB/dotnet/Memory_Leak_Detection.aspx

1

si vous êtes sûr que les objets ne coûtent référencés plus nulle part, vous pouvez forcer un appel au collecteur d'ordures avec gc .Collect()