Estoy tratando de entender mejor el concepto de pérdida de memoria. ¿Alguien puede señalar alguna información útil que me ayude a comprender mejor qué filtraciones de memoria hay y cómo las encontraría en mi código?Memory Leaks C#
Gracias
Estoy tratando de entender mejor el concepto de pérdida de memoria. ¿Alguien puede señalar alguna información útil que me ayude a comprender mejor qué filtraciones de memoria hay y cómo las encontraría en mi código?Memory Leaks C#
Gracias
una pérdida de memoria cuando el programa asigna dinámicamente la memoria que no consigue adecuadamente cancela la asignación después de que haya terminado de usarlo. Si tienes un programa que hace esto continuamente, tu fuga será cada vez más grande y muy pronto tu programa ocupará toda tu memoria RAM.
También hay algunas sugerencias útiles que se encuentran aquí: What strategies and tools are useful for finding memory leaks in .NET?
favor vaya a través de este artículo: http://www.codeproject.com/KB/dotnet/Memory_Leak_Detection.aspx
Una muy buena lectura es Everybody thinks about garbage collection the wrong way.
En general, una pérdida de memoria, o cualquier fuga de recursos, es siempre que el programa asigna memoria (o cualquier otro recurso) y luego omite desasignarlo cuando termina con él. En la memoria de aplicación nativa, la fuga es la pérdida de recursos más común y puede ocurrir cuando la referencia del recurso (el puntero al bloque asignado) sale del alcance y se destruye, pero el recurso asignado (el bloque de memoria) no se destruye. En este caso, el recurso (memoria) se ha filtrado porque el programa ha perdido la capacidad de liberarlo, incluso si lo desea, porque ya no recuerda la ubicación del recurso (la dirección del bloque).
En las aplicaciones administradas, las fugas de memoria son un poco más complicadas. Como el tiempo de ejecución puede rastrear automáticamente las referencias a los recursos, también puede comprender cuándo un recurso (un objeto) ya no está referenciado por ninguna parte activa de la aplicación (no hay una cadena de referencias de un marco de pila a ese recurso en ningún hilo) y por lo tanto, el tiempo de ejecución puede comprender cuándo es seguro recoger los objetos que ya no son referencias de la aplicación. Entonces en el mundo administrado, una "fuga" ocurriría cuando crees que la aplicación ya no hace referencia a un objeto (y por lo tanto puede ser recolectada por el tiempo de ejecución) pero de hecho, a través de alguna cadena de referencias, do tienes una referencia a y por lo tanto no puede ser recolectado.
Recomiendo encarecidamente el artículo de Raymond Chen vinculado anteriormente, es muy muy esclarecedor.
Una pérdida de memoria tradicional ocurre cuando asigna memoria, y luego de alguna manera "olvida" liberarla. En el antiguo código C++, eso significa llamar al new
sin un delete
correspondiente. En C, significó una llamada a alloc()
/malloc()
sin un correspondiente free()
.
En .Net, no obtienes fugas de memoria en el sentido tradicional, porque no se supone que debes liberar memoria. En cambio, confías en el recolector de basura para que lo libere por ti. Sin embargo, esto no significa que nunca perderás el rastro de la memoria. Hay varias maneras en que puede guardar accidentalmente una referencia que evite que el recolector de basura haga su trabajo. Estos incluyen variables globales (especialmente listas, dictionarys y otros objetos que podrían usarse para "almacenar en caché" objetos), controladores de eventos que se cuelgan en la memoria, referencias de historial recursivo y el montón de objetos grandes.
También es importante señalar aquí que el hecho de que vea un patrón de aumento de uso de memoria en .Net no significa necesariamente que su aplicación tenga pérdidas de memoria. En los casos de baja presión de memoria general, el recolector de basura podría simplemente optar por ahorrar tiempo al no recopilar todavía, o al recopilar pero no devolver la memoria al sistema operativo.
¿sería "C++ viejo" C++ sin punteros inteligentes por casualidad? – user666412
Hay muchos tipos de pérdidas de memoria, pero en general el término se refiere a algún tipo de recurso que ya no se utiliza, pero que aún ocupa memoria. Si tienes muchos de ellos, tu aplicación requiere mucha memoria y, finalmente, te quedas sin ella.
En C#, estas son algunas pérdidas de memoria comunes:
Dispose()
en todos los objetos IDisposable
. Use the using
statement."Memory leak" debe definirse como "memoria que se utiliza cuando USTED cree que no se debe usar" para aplicar a lenguajes/tiempos de ejecución recogidos como C#/Java.
Tradicionalmente, "pérdida de memoria" se define como memoria que no está desasignada correctamente (consulte el enlace de wikipedia en otras respuestas) que generalmente no ocurre en entornos recolectados. Tenga en cuenta que debido a problemas con el tiempo de ejecución, incluso los lenguajes recolectados pueden tener pérdidas de memoria, es decir, incluso si JavaScript es un lenguaje basura, era fácil filtrar una gran cantidad de objetos JavaScript en el tiempo de ejecución de JavaScript de Internet Explorer.
Cuando se asigna memoria a una aplicación, la aplicación tiene la obligación de devolver esa memoria al sistema operativo para que pueda ser reutilizada por otras aplicaciones. Se produce una pérdida de memoria cuando una aplicación no libera esa memoria, lo que impide su reasignación.
Para el código administrado, el recolector de basura rastrea las referencias a los objetos creados por una aplicación. Para la mayoría de las situaciones, el CLR gestionará la asignación de memoria y la desasignación de forma transparente y de forma razonable en nombre del proceso en ejecución. Sin embargo, los desarrolladores de .NET aún deben considerar la gestión de recursos, ya que todavía hay situaciones en las que la memoria puede filtrarse a pesar del trabajo del recolector de basura.
Considere el siguiente código:
Widget widget = new Widget();
La línea de código anterior crea una nueva instancia de la clase Widget y el campo widget es asignada una referencia a ese objeto. GC realiza un seguimiento de las referencias asociadas con cada objeto y desasigna la memoria de los objetos para los que no hay referencias sólidas.
Vale la pena mencionar que la recolección de basura de CLR solo recopilará objetos administrados, el código .NET puede hacer uso frecuente de recursos no administrados que no se pueden recolectar de forma automática.
Las fugas de recursos no administradas ocurren cuando el objeto para el que se asignaron los recursos no las asigna correctamente antes de que la última referencia a esos recursos salga del ámbito, lo que deja los recursos asignados pero sin referencia y por lo tanto inutilizables para la aplicación.
Las clases que hacen referencia directamente a los recursos no administrados deben garantizar que esos recursos se desasignan correctamente.Un ejemplo de hacer esto sería algo como esto:
public void ManagedObject : IDisposable
{
//A handle to some native resource.
int* handle;
public ManagedObject()
{
//AllocateHandle is a native method called via P/Invoke.
handle = AllocateHandle();
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (disposing)
{
//deal with managed resources here
FreeHandle(handle);
}
}
~ManagedType()
{
Dispose(false);
}
}
El parámetro disposing
es falsa cuando se llama desde un finalizador. Esto es para evitar que se utilicen los recursos administrados desde el finalizador, ya que las referencias administradas deben considerarse no válidas en esa etapa.
Tenga en cuenta también que el método Dispose()
llama al GC.SuppressFinalize(this)
, lo que impide que el finalizador se ejecute para esa instancia. Esto se hace porque los recursos que se habrían desasignado en el finalizador se desasignaron en la llamada Dispose haciendo que la invocación de un fializador sea innecesaria.
código de cliente que hace uso de las clases que manejan los recursos no administrados (o cualquier clase que implementa IDisposable) debe hacerlo dentro de un bloque using
para asegurar que el IDisposable.Dispose
se llama cuando el acceso a los recursos ya no es necesario ya que esto se llevará a cuidado de los recursos administrados y no administrados y, en el caso del ejemplo anterior, garantizar que no se realice una llamada muy costosa al finalizador.
Appoligies for my rambling. Me detendré ahora.
Registro de Windows → Buscar → "HeapLeakDetection" – Bitterblue
Aquí hay una publicación de blog que hice hace un tiempo en .Filtros de memoria .Net: http://crazorsharp.blogspot.com/2009/03/net-memory-leaks-it-is -possible.html – BFree
¿Cómo diablos no tiene este tema? Él quiere saber sobre fugas de memoria, eso es directamente responsable y directamente relevante, en mi humilde pero correcta opinión. –