Pérdida de memoria con ContextMenuStrip

Estoy creando una gran cantidad de controles personalizados y los agrego a un FlowLayoutPanel. También hay un ContextMenuStrip creado y completado en el momento del diseño.

Cada vez que se agrega un control al panel, tiene su propiedad ContextMenuStrip asignada a este menú, de modo que todos los controles “comparten” el mismo menú. Pero noté que cuando se quitan los controles del panel y se eliminan, la memoria en uso en el Administrador de tareas no se cae. Aumenta alrededor de 50kB cada vez que se crea un control y se agrega al panel de diseño.

Descargué la versión de prueba de .NET Memory Profiler y demostré que había referencias a la tira de menú que estaba después de que se eliminaran los controles. Cambié el código para establecer explícitamente la propiedad ContextMenuStrip en nulo antes de deshacerse del control, y sí, ahora se libera la memoria. ¿Por qué es esto? ¿No debería el GC limpiar este tipo de cosas?

Si echas un vistazo a la propiedad ContexmenuStrip de Control, verás que el colocador suscribe el control al evento Disposed del MenuStrip, creando una referencia del MenuStrip al Control.

Esto significa que es un caso clásico de evento alcanzable y ya encontró la solución: establezca la propiedad ContexmenuStrip en nulo.

Siempre debe disponer de ContextMenuStrip en caso de que lo cree dinámicamente. Esto se debe a que cada vez se crea un controlador nativo, pero no se destruye. Esto significa que si crea un menú contextual y lo muestra, luego lo cierra y lo muestra de nuevo y se quedará sin manijas.