不久前,我发布了一个关于我的程序实际上是如何泄漏内存的问题:请参见
here
. 现在,我专门跟踪了一些代码,在这些代码中,我将位图对象的原始字节复制到托管数组中。相关规范:
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);
}
}
所以这就是导致内存无法恢复的所有代码范围,我认为它与marshal.copy()有关,尽管我假设从位图(自己清理?)复制之后。对于托管数组,没有问题。
因此,问题是:是否需要通过IDisposable接口或类似的方式清理位图对象。在这种情况下使用marshal.copy()有什么内在的错误(如果有什么问题的话),在哪里可以清除这个问题?
谢谢你
正如您所知,我已经测试了以下代码,以验证这确实是导致问题的原因:
Bitmap bmp = new Bitmap(1000, 1000);
for (int n = 0; n < 100; ++n)
{
FastBitmap fb = new FastBitmap(bmp);
}
在这个序列的开始和结束时,总的内存使用量增加了320MB,并且不会消失,不管您等待了多长时间。