2011-05-17 16 views
7

Tengo un .NET System.Threading. Temporizador de temporizador que marca cada 60 segundos e introduce una pérdida de memoria en cada tic.Cuando mi temporizador marca ... .NET Memory Leak

En cada tic del temporizador, el código asigna un objeto IDisposable (llamado SocketsMessageConnector) ... pero lo desecho correctamente.

Ejecuté .NET Memory Profiler y cada 60 segundos veo una nueva instancia de mi clase SocketsMessageConnector en la memoria (así que después de 15 minutos, tengo 15 instancias). El perfilador de memoria verifica que la instancia está de hecho dispuesta, pero muestra la instancia rooteada por un TimerCallback, que está rooteado por un _TimerCallback, que está rooteado por un GCH y ...

¿Qué hay aquí? ¿Por qué el TimerCallback se mantiene en la nueva instancia creada en cada temporizador?

PS. El generador de perfiles fuerza 2 GC antes de tomar una instantánea, por lo que sé que ES de hecho una fuga y no solo una optimización por parte del GC.

+0

¿Puede publicar algún código para que podamos ver? – Nate

+5

Leí la pregunta y pensé: "A medida que mi temporizador gotea suavemente" –

Respuesta

7

El hecho de que se haya desechado no significa que todavía se haya recogido basura.

Intente cambiar su temporizador para que se ejecute dos veces por segundo, y luego déjelo funcionar durante 10 minutos. Ahora compruebe cuántos de los objetos de su clase todavía "permanecen en la memoria". Si realmente tiene una pérdida de memoria, tendrá 1200 objetos. Pero si Garbage Collection ha saltado, tendrá considerablemente menos, tal vez menos de 100.

+0

El generador de perfiles fuerza dos recolecciones de basura, lo que habría pensado que sería suficiente para limpiar instancias no referenciadas ... pero de todos modos, lo he visto levantarse a 150 instancias. Voy a hacer el temporizador más pequeño e intentaré también ... – Jeff

+0

Bueno, es muy extraño ... Cambié el intervalo para ejecutar cada 100 ms ... y una vez que la memoria se elevó por encima de 200 MB, comenzó a GC correctamente y comenzaron instancias antiguas desaparecer ... – Jeff

+0

Recuerde, la recopilación no necesariamente ocurre hasta que el GC decide que es un buen momento. Además, la memoria entregada a su aplicación por el sistema operativo no será devuelta inmediatamente una vez que CLR ya no la necesite. La asignación de memoria es bastante complicada. Mire Process Explorer y observe a Mark Russinovich explicar todas las diferentes columnas de memoria y verá a qué me refiero. – Tom