Speicherleck mit ContextMenuStrip

8

Ich erstelle viele benutzerdefinierte Steuerelemente und füge sie zu einem FlowLayoutPanel hinzu. Es gibt auch einen ContextMenuStrip, der zur Entwurfszeit erstellt und gefüllt wird.

Jedes Mal, wenn dem Panel ein Steuerelement hinzugefügt wird, wird diesem Menü die Eigenschaft ContextMenuStrip zugewiesen, sodass alle Steuerelemente dasselbe Menü "freigeben". Aber mir ist aufgefallen, dass die im Task-Manager verwendeten Speicher nicht gelöscht werden, wenn die Steuerelemente aus dem Bedienfeld entfernt und entsorgt werden. Bei jedem Erstellen eines Steuerelements und beim Hinzufügen zum Layout-Bedienfeld steigt es um 50 KB.

Ich habe die Testversion von .NET Memory Profiler heruntergeladen, und es zeigte, dass nach dem Ablegen der Steuerelemente Verweise auf die Menüleiste vorhanden waren. Ich habe den Code so geändert, dass die ContextMenuStrip -Eigenschaft vor dem Entfernen des Steuerelements explizit auf null gesetzt wurde, und yep, der Speicher ist jetzt freigegeben. Warum ist das? Sollte der GC diese Art von Sache nicht bereinigen?

    
Dave 08.05.2010, 00:28
quelle

2 Antworten

5

Wenn Sie sich die ContexmenuStrip-Eigenschaft von Control ansehen, werden Sie feststellen, dass der Setter das Steuerelement für das Disposed-Ereignis des MenuStrip abonniert und eine Rückreferenz vom MenuStrip zum Control erstellt.

Dies bedeutet, dass es sich um einen klassischen Fall des Erreichbaren-über-Ereignisses handelt und Sie bereits die Lösung gefunden haben: Setzen Sie die ContexmenuStrip-Eigenschaft auf null.

    
Henk Holterman 08.05.2010, 10:33
quelle
0

Sie sollten ContextMenuStrip immer dann entfernen, wenn Sie es jedes Mal dynamisch erstellen. Dies liegt daran, dass jedes Mal ein natives Handle erstellt, aber nicht zerstört wird. Das bedeutet, wenn Sie das Kontextmenu erstellen und es anzeigen, dann schließen Sie es und zeigen Sie es erneut an, dann haben Sie keine Griffe mehr.

    
Trivalik 02.08.2017 09:40
quelle

Tags und Links