[C#] ¿Qué estrategias y herramientas son útiles para encontrar fugas de memoria en .NET?


Answers

Solo por el problema del olvido para deshacerse, pruebe la solución que se describe en esta publicación de blog . Aquí está la esencia:

    public void Dispose ()
    {
        // Dispose logic here ...

        // It's a bad error if someone forgets to call Dispose,
        // so in Debug builds, we put a finalizer in to detect
        // the error. If Dispose is called, we suppress the
        // finalizer.
#if DEBUG
        GC.SuppressFinalize(this);
#endif
    }

#if DEBUG
    ~TimedLock()
    {
        // If this finalizer runs, someone somewhere failed to
        // call Dispose, which means we've failed to leave
        // a monitor!
        System.Diagnostics.Debug.Fail("Undisposed lock");
    }
#endif
Question

Escribí C ++ por 10 años. Me encontré con problemas de memoria, pero podrían solucionarse con una cantidad razonable de esfuerzo.

Durante los últimos años he estado escribiendo C #. Me parece que todavía tengo muchos problemas de memoria. Son difíciles de diagnosticar y corregir debido a la falta de determinación y porque la filosofía de C # es que no debes preocuparte por esas cosas cuando definitivamente lo haces.

Un problema particular que encuentro es que tengo que eliminar y limpiar todo en el código explícitamente. Si no lo hago, entonces los perfiladores de memoria realmente no ayudan porque hay tanto desperdicio que no se puede encontrar una filtración dentro de todos los datos que están tratando de mostrar. Me pregunto si tengo una idea equivocada o si la herramienta que tengo no es la mejor.

¿Qué tipo de estrategias y herramientas son útiles para abordar fugas de memoria en .NET?




Este blog tiene algunos recorridos realmente maravillosos que usan windbg y otras herramientas para rastrear fugas de memoria de todo tipo. Excelente lectura para desarrollar tus habilidades.




Desde Visual Studio 2015, considere utilizar la herramienta de diagnóstico Uso de la memoria para recopilar y analizar datos de uso de la memoria.

La herramienta Uso de memoria le permite tomar una o más instantáneas del montón de memoria administrada y nativa para ayudar a comprender el impacto en el uso de memoria de los tipos de objetos.




Si las filtraciones que está observando se deben a una implementación de caché desbocada, este es un escenario en el que es posible que desee considerar el uso de WeakReference. Esto podría ayudar a garantizar que la memoria se libera cuando sea necesario.

Sin embargo, en mi humilde opinión, sería mejor considerar una solución a medida, solo usted realmente sabe cuánto tiempo necesita para mantener los objetos alrededor, por lo que diseñar el código de limpieza adecuado para su situación suele ser el mejor enfoque.




Una de las mejores herramientas es usar las herramientas de depuración para Windows y tomar un volcado de memoria del proceso usando adplus , luego usar windbg y el complemento sos para analizar la memoria de proceso, los subprocesos y las pilas de llamadas.

También puede usar este método para identificar problemas en los servidores, después de instalar las herramientas, compartir el directorio, luego conectarse al recurso compartido desde el servidor usando (uso neto) y realizar un bloqueo o volcar el proceso.

Luego analiza fuera de línea.




Todavía debe preocuparse por la memoria cuando está escribiendo código administrado a menos que su aplicación sea trivial. Sugeriré dos cosas: primero, lea CLR a través de C # porque lo ayudará a comprender la gestión de memoria en .NET. En segundo lugar, aprenda a usar una herramienta como CLRProfiler (Microsoft). Esto puede darle una idea de lo que está causando su pérdida de memoria (por ejemplo, puede echar un vistazo a la fragmentación de gran montón de objetos)




Después de una de mis correcciones para la aplicación administrada, tuve la misma idea, por ejemplo, cómo verificar que mi aplicación no tenga la misma pérdida de memoria después del siguiente cambio, así que escribí algo así como el marco Verificación de la versión del objeto, eche un vistazo a el paquete ObjectReleaseVerification . Puede encontrar un ejemplo aquí https://github.com/outcoldman/OutcoldSolutions-ObjectReleaseVerification-Sample , e información sobre este ejemplo http://outcoldman.ru/en/blog/show/322