Escribí C ++ por 10 años. Encontré problemas de memoria, pero podrían solucionarse con un esfuerzo razonable.
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 debería tener que preocuparse por esas cosas cuando definitivamente lo hace.
Un problema particular que encuentro es que tengo que disponer y limpiar explícitamente todo en el código. Si no lo hago, entonces los perfiladores de memoria realmente no ayudan porque hay tanta paja flotando sobre ti que no puedes encontrar una fuga en todos los datos que intentan mostrarte. 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 las pérdidas de memoria en .NET?
fuente
Respuestas:
Uso MemProfiler de Scitech cuando sospecho una pérdida de memoria.
Hasta ahora, he encontrado que es muy confiable y poderoso. Me ha salvado el tocino en al menos una ocasión.
El GC funciona muy bien en .NET IMO, pero al igual que cualquier otro lenguaje o plataforma, si escribe un código incorrecto, suceden cosas malas.
fuente
Solo por el problema de olvidar deshacerse, pruebe la solución descrita en esta publicación de blog . Aquí está la esencia:
fuente
Hemos utilizado el software Ants Profiler Pro de Red Gate en nuestro proyecto. Funciona realmente bien para todas las aplicaciones basadas en lenguaje .NET.
Descubrimos que .NET Garbage Collector es muy "seguro" en la limpieza de objetos en memoria (como debería ser). Mantendría objetos alrededor solo porque podríamos estar usándolo en algún momento en el futuro. Esto significaba que teníamos que tener más cuidado con la cantidad de objetos que inflamos en la memoria. Al final, convertimos todos nuestros objetos de datos en un "inflado a pedido" (justo antes de que se solicite un campo) para reducir la sobrecarga de memoria y aumentar el rendimiento.
EDITAR: Aquí hay una explicación adicional de lo que quiero decir con "inflar bajo demanda". En nuestro modelo de objetos de nuestra base de datos, utilizamos las propiedades de un objeto primario para exponer los objetos secundarios. Por ejemplo, si tuviéramos algún registro que hiciera referencia a algún otro registro de "detalle" o "búsqueda" de forma individual, lo estructuraríamos así:
Descubrimos que el sistema anterior creó algunos problemas reales de memoria y rendimiento cuando había muchos registros en la memoria. Entonces cambiamos a un sistema donde los objetos se inflaban solo cuando se solicitaban, y las llamadas a la base de datos se realizaban solo cuando era necesario:
Esto resultó ser mucho más eficiente porque los objetos se mantuvieron fuera de la memoria hasta que se necesitaron (se accedió al método Get). Proporcionó un aumento de rendimiento muy grande al limitar los accesos a la base de datos y una gran ganancia en espacio de memoria.
fuente
Aún debe preocuparse por la memoria cuando escribe 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 administración de memoria en .NET. Segundo, aprenda a usar una herramienta como CLRProfiler (Microsoft). Esto puede darle una idea de lo que está causando la pérdida de memoria (por ejemplo, puede echar un vistazo a la fragmentación del montón de objetos grandes)
fuente
¿Estás usando código no administrado? Si no está utilizando código no administrado, según Microsoft, las pérdidas de memoria en el sentido tradicional no son posibles.
Sin embargo, es posible que la memoria utilizada por una aplicación no se libere, por lo que la asignación de memoria de una aplicación puede crecer a lo largo de la vida útil de la aplicación.
Para tratar este tipo de problema, puede implementar IDisposable . Si desea ver algunas de las estrategias para lidiar con la administración de memoria, le sugiero que busque IDisposable, XNA, administración de memoria ya que los desarrolladores de juegos deben tener una recolección de basura más predecible y, por lo tanto, deben obligar al GC a hacer lo suyo.
Un error común es no eliminar los controladores de eventos que se suscriben a un objeto. Una suscripción de controlador de eventos evitará que un objeto sea reciclado. Además, eche un vistazo a la declaración de uso que le permite crear un alcance limitado para la vida útil de un recurso.
fuente
Este blog tiene algunos tutoriales realmente maravillosos que usan windbg y otras herramientas para rastrear fugas de memoria de todo tipo. Excelente lectura para desarrollar tus habilidades.
fuente
Acabo de tener una pérdida de memoria en un servicio de Windows, que arreglé.
Primero, probé MemProfiler . Lo encontré realmente difícil de usar y nada fácil de usar.
Luego, utilicé JustTrace, que es más fácil de usar y le brinda más detalles sobre los objetos que no están dispuestos correctamente.
Me permitió resolver la pérdida de memoria con mucha facilidad.
fuente
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 se libere memoria 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, por lo que diseñar el código de limpieza adecuado para su situación suele ser el mejor enfoque.
fuente
Prefiero dotmemory de Jetbrains
fuente
Big guns - Herramientas de depuración para Windows
Esta es una increíble colección de herramientas. Puede analizar los montones administrados y no administrados con él y puede hacerlo sin conexión. Esto fue muy útil para depurar una de nuestras aplicaciones ASP.NET que siguió reciclando debido al uso excesivo de la memoria. Solo tuve que crear un volcado de memoria completa del proceso vivo que se ejecuta en el servidor de producción, todo el análisis se realizó sin conexión en WinDbg. (Resultó que algunos desarrolladores estaban usando en exceso el almacenamiento de sesión en memoria).
El blog "Si está roto es ..." tiene artículos muy útiles sobre el tema.
fuente
Lo mejor a tener en cuenta es realizar un seguimiento de las referencias a sus objetos. Es muy fácil terminar colgando referencias a objetos que ya no te importan. Si ya no va a usar algo, deshágase de él.
Acostúmbrese a usar un proveedor de caché con vencimientos deslizantes, de modo que si algo no se hace referencia durante un período de tiempo deseado, se desreferencia y se limpia. Pero si se accede mucho, dirá en la memoria.
fuente
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 sos complemento para analizar la memoria del proceso, los hilos y las pilas de llamadas.
También puede usar este método para identificar problemas en los servidores, después de instalar las herramientas, comparta el directorio, luego conéctese al recurso compartido desde el servidor utilizando (uso neto) y realice un bloqueo o cuelgue el proceso.
Luego analice sin conexión.
fuente
Después de una de mis correcciones para la aplicación administrada tuve lo mismo, como cómo verificar que mi aplicación no tendrá la misma pérdida de memoria después de mi próximo cambio, así que escribí algo como el marco de verificación de liberación de objetos, por favor, eche un vistazo el paquete NuGet ObjectReleaseVerification . Puede encontrar una muestra aquí https://github.com/outcoldman/OutcoldSolutions-ObjectReleaseVerification-Sample , e información sobre esta muestra http://outcoldman.ru/en/blog/show/322
fuente
Desde Visual Studio 2015, considere utilizar la herramienta de diagnóstico de uso de memoria lista para usar para recopilar y analizar datos de uso de 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 del uso de memoria de los tipos de objetos.
fuente
Una de las mejores herramientas que utilicé es DotMemory. Puede usar esta herramienta como una extensión en VS.Después de ejecutar su aplicación, puede analizar cada parte de la memoria (por Objeto, NameSpace, etc.) que usa su aplicación y tomar una instantánea de eso , Compárelo con otros SnapShots. DotMemory
fuente