2010-02-05 14 views
5

Analizo un proyecto de VB.NET y hay algunos objetos (formulario MDI infantil) que se eliminan pero no se eliminan con el GC.Controlador de eventos y pérdidas de memoria

El análisis MemoryProfiler encuentran, entre otros, los siguientes:.

"Esta instancia está dispuesto y todavía indirectamente arraigados por un manejador de sucesos A menudo, esto indica que el manejador de sucesos no ha sido adecuadamente eliminado y es una causa común de pérdidas de memoria. Los ejemplos a continuación son directamente arraigado por manejador de sucesos (s). a investigar para obtener más información sobre este problema ..."

Ahora, trato de descubrir qué debería significar esto y cómo solucionarlo.

Tengo un formulario MDI y un formulario hijo. El GC no recoge el formulario secundario después de abrir/cerrar, aparentemente porque permanece inmóvil (¿indirectamente?) Referenciado por MDIForm EventHandlerList ...

¿Qué puede ser y cómo puedo solucionarlo?

probé el corrección recomendada en this thread, porque tenía un problema con la referencia MDI en el PropertyStore, ahora esto eliminó, pero apareció la referencia MDI EventHandlerList a la forma infantil ...

Después de un análisis de código I observado algunos

AddHandler newMenu.Click, AddressOf ClickMenu 

sin precedentes con RemoveHandler newMenu.Click, AddressOf ClickMenu. ¿Podría ser la causa principal?

Y, a propósito, es el Handles

Private Sub ClickMenu(sender as Object, e as EventArgs) Handles newMenu.Click 

mejor que

RemoveHandler newMenu.Click, AddressOf ClickMenu 
AddHandler newMenu.Click, AddressOf ClickMenu 

desde el punto de vista de la asignación de memoria?

+0

Un fragmento del código puede ayudar. En particular, los controladores de eventos de agregar y quitar y eliminar el código. –

+0

¿Llamar a GC.Collect() después de la eliminación hace alguna diferencia? El hecho de que algo se elimine no siempre significa que es basura recogida de inmediato. – Ian

+0

También ... ¿esto es realmente un problema? Leer un foro al que te has vinculado sugiere que esto no empeorará con el tiempo. ¿Algunos de los microbits filtrados a través del código MS van a tener un gran impacto? – Ian

Respuesta

4

El EventHandlerList es utilizado por las clases que proporcionan grandes cantidades de eventos para manejar la memoria de manera más eficiente al solo asignar espacio para el campo de respaldo de eventos cuando es necesario en lugar de cuando se declara el evento. Todos los eventos para el formulario principal se almacenan allí.

Me esperaba que el formulario hijo estuviera supervisando cuando su padre puede cerrar (este es un caso de uso común) y no se dio de baja del evento FormClosing o FormClosed cuando recibió ese evento. Sin embargo, eso es solo una suposición.Para confirmar, consulte la implementación de su formulario hijo y busque todos los casos en que se suscriba a eventos del formulario principal, luego asegúrese de que haya una cancelación de suscripción correspondiente a esos eventos.

actualización
El controlador de menú que encontró que no se quitó bien podría ser el origen del problema que se ve. Intente agregar la llamada de eliminación y vea si eso soluciona la fuga.

2

Hay otro objeto que hace referencia al objeto que debe ser eliminado por el GC a través de un controlador de eventos. Significado: hay otro objeto que aún está suscrito a un evento del objeto eliminado.

Puede resolver esto anulando la suscripción al evento (elimine los manejadores de eventos del evento), cuando desee deshacerse de ese objeto.

Cuestiones relacionadas