Tengo un problema de pérdida de memoria en mi aplicación que carga una gran cantidad de imágenes. Soy bastante nuevo en C#, y pensé que mis días de problemas de pérdida de memoria habían pasado. No puedo resolver el problema. ¿Tal vez estoy usando algunos módulos no administrados que no manejo correctamente?Fuga de memoria de carga de imagen con C#
Para ilustrar mi problema, he simplificado el núcleo de las causas del problema y lo he trasladado a un proyecto limpio. Tenga en cuenta que todo esto es un código tonto que no refleja la aplicación original de donde vino. En la aplicación de prueba tengo 2 botones, activando dos eventos.
Botón 1 - Crear: establecer un objeto en el contexto de datos. Esto cargará las imágenes y mantenerlos vivos estableciendo el objeto a la DataContext:
var imgPath = @"C:\some_fixed_path\img.jpg";
DataContext = new SillyImageLoader(imgPath);
Botón 2 - Limpieza: Mi opinión es que si suelto de la retención de referencia del SillyImageLoader que a su vez mantiene las imágenes, a continuación, esto será eliminado También exploto explícitamente la recolección de basura solo para ver inmediatamente la cantidad de memoria después de eliminar la referencia.
DataContext = null;
System.GC.Collect();
Cuando estoy probando estoy cargando una imagen de 974KB jpeg. Tener 30 representaciones de mapas de bits de esto aumenta el uso de memoria de mi aplicación de ~ 18MB a ~ 562MB. De acuerdo. Pero cuando llego a la limpieza, la memoria solo baja a ~ 292MB. Si repito Create + CleanUp, me quedan otros ~ 250 MB de memoria. Entonces, obviamente, alguien todavía tiene algo.
Aquí es el SillyImageLoader-código:
namespace MemoryLeakTest
{
using System;
using System.Drawing;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Media.Imaging;
public class SillyImageLoader
{
private BitmapSource[] _images;
public SillyImageLoader(string path)
{
DummyLoad(path);
}
private void DummyLoad(string path)
{
const int numberOfCopies = 30;
_images = new BitmapSource[numberOfCopies];
for (int i = 0; i < numberOfCopies; i++)
{
_images[i] = LoadImage(path);
}
}
private static BitmapSource LoadImage(string path)
{
using (var bmp = new Bitmap(path))
{
return Imaging.CreateBitmapSourceFromHBitmap(
bmp.GetHbitmap(),
IntPtr.Zero,
Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
}
}
}
}
¿Alguna idea? El problema parece ser con BitmapSource. Manteniendo solo el mapa de bits, no hay pérdida de memoria. Estoy usando BitmapSource para poder configurar esto en la propiedad de Origen de una Imagen. ¿Debo hacer esto de manera diferente? Si es así, aún me gustaría saber la respuesta de la fuga de memoria.
Gracias.
¿Quién llama Deshace el BitmapSource devuelto por LoadImage? –
Pensé que esto, de hecho publicó una respuesta basada en él, pero no puedo ver una disposición en BitmapSource (he eliminado la respuesta) –
¿Cómo se está monitoreando el uso de la memoria de su aplicación? ¿Administrador de tareas? –