Publiqué una pregunta no hace mucho sobre cómo mi programa esencialmente tenía una pérdida de memoria: vea here. Ahora lo he rastreado específicamente a algún código en el que copie los bytes sin formato de un objeto Bitmap en una matriz administrada. El código en cuestión:Uso seguro de Marshal.Copia de datos brutos de mapas de bits a la matriz administrada
public class FastBitmap
{
...
private byte[] rgbValues;
private int height;
private int width;
private Bitmap image;
public FastBitmap(Bitmap plainBitmap)
{
width = plainBitmap.Width;
height = plainBitmap.Height;
image = new Bitmap(plainBitmap);
LockPixels(new Rectangle(0, 0, image.Width, image.Height));
}
private void LockPixels(Rectangle area)
{
if (locked)
return;
locked = true;
BitmapData bitmapData = image.LockBits(area, ImageLockMode.ReadWrite,
PixelFormat.Format24bppRgb);
IntPtr ptr = bitmapData.Scan0;
int stride = bitmapData.Stride;
int numBytes = image.Width * image.Height * 3;
rgbValues = new byte[numBytes];
for (int r = 0; r < image.Height; ++r)
Marshal.Copy(new IntPtr((int)ptr + stride * r),
rgbValues, image.Width * 3 * r, image.Width * 3);
}
}
Así que eso es todo el alcance del código que está causando la memoria no se está recuperando, y me imagino que tiene algo que ver con la Marshal.Copy() aunque había asumido que desde que estaba copiando de un mapa de bits (¿se había limpiado solo?) a una matriz administrada, no había ningún problema.
Entonces la pregunta: ¿Es necesario limpiar el objeto Bitmap, ya sea a través de una interfaz IDisposable, o algo similar. ¿Qué (si hay algo) es intrínsecamente incorrecto con el uso de Marshal.Copy() en esta situación, y dónde puedo solucionar el problema?
Gracias
Para que sepan que he probado el siguiente código, para verificar que efectivamente es esta la causa del problema:
Bitmap bmp = new Bitmap(1000, 1000);
for (int n = 0; n < 100; ++n)
{
FastBitmap fb = new FastBitmap(bmp);
}
Al principio y al final de esta secuencia de la memoria global el uso se ha incrementado en algo así como 320 MB y no desaparece, independientemente de cuánto tiempo espere.
Muchas gracias, horas de frustración y es tan simple como eso. – DeusAduro
Parece que se pierde el segundo fragmento de código, la función 'UnlockBitmap' (que llama a 'UnlockBits'), de este artículo: http://www.devx.com/webdev/Article/44658/1763/page/2 – rwong