2010-05-08 3 views
8

Je crée beaucoup de contrôles personnalisés et je les ajoute à un FlowLayoutPanel. Il y a aussi un ContextMenuStrip créé et rempli au moment du design.Fuite de mémoire avec ContextMenuStrip

Chaque fois qu'un contrôle est ajouté au panneau, sa propriété ContextMenuStrip est affectée à ce menu, de sorte que tous les contrôles "partagent" le même menu. Mais j'ai remarqué que lorsque les contrôles sont supprimés du panneau et éliminés, la mémoire utilisée dans le Gestionnaire des tâches ne tombe pas. Il augmente d'environ 50 Ko chaque fois qu'un contrôle est créé et ajouté au panneau de disposition.

J'ai téléchargé le procès de .NET Memory Profiler et il a montré qu'il y avait des références à la bande de menu qui traîne après que les contrôles ont été éliminés. J'ai changé le code pour définir explicitement la propriété ContextMenuStrip à null avant de disposer du contrôle, et oui, la mémoire est maintenant libérée. Pourquoi est-ce? Le GC ne devrait-il pas nettoyer ce genre de choses?

+0

http://connect.microsoft.com/VisualStudio/feedback/details/116059/contextmenustrip-memory-leak – CharithJ

Répondre

5

Si vous jetez un coup d'oeil à la propriété ContexmenuStrip de Control, vous verrez que le setter souscrit le contrôle à l'événement Disposed du MenuStrip, créant une référence arrière à partir du MenuStrip au contrôle. Cela signifie qu'il s'agit d'un cas classique d'accès accessible et que vous avez déjà trouvé la solution: définissez la propriété ContexmenuStrip sur Null.

+0

Merci Henk. Je suis nouveau à C# mais comprenez l'essentiel de ce que vous voulez dire. Mais pourquoi tant de mémoire? Après avoir découvert cette fuite, j'ai réalisé que je ne me désinscrivais pas de certains événements personnalisés dans mes propres classes avant de détruire les instances. Et pourtant, cela ne semblait pas entraîner une augmentation de la consommation de mémoire. Ou est-ce une bête différente? – Dave

+1

Notez qu'il est asymétrique, si vous aviez disposé le ContextMenu il n'y aurait pas de problème. Je considérerais ceci comme un défaut de conception probable de ContextMenuStrip, il est sournois de back-link comme ça. Méfiez-vous de cela dans vos propres cours. Mais quand une classe d'abonnement est Disposé il n'y a pas de problème. –

+0

Oh ok. Merci. Je suppose que c'est un problème rare dans le framework .net alors? Sans l'utilisation d'un profileur de mémoire, je n'aurais probablement pas compris ce petit diable. – Dave

0

Vous devez toujours disposer ContextMenuStrip au cas où vous le créeriez dynamiquement. C'est parce que chaque fois est un handle natif créé, mais pas détruit. Cela signifie que si vous créez un menu contextuel et que vous le montrez, fermez-le et affichez-le de nouveau, vous manquerez de poignées.