我不久前发布了一个问题,关于我的程序本质上是如何泄漏内存:请参阅
here.我现在已经专门跟踪了一些代码,其中我将Bitmap对象的原始字节复制到托管数组中.相关代码:
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,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()有关,虽然我曾经假设我从Bitmap复制(自己清理) ?)到托管阵列,没有问题.
所以问题是:是否有必要通过IDisposable接口或类似方法清理Bitmap对象.在这种情况下使用Marshal.Copy()本身是什么(如果有的话)本质上是错误的,我在哪里可以清理问题?
谢谢
只是你知道我已经测试了下面的代码,以验证它确实导致了这个问题:
Bitmap bmp = new Bitmap(1000,1000); for (int n = 0; n < 100; ++n) { FastBitmap fb = new FastBitmap(bmp); }
在此序列的开始和结束时,总体内存使用量增加了320mb,并且不会消失,无论您等待多长时间.
解决方法
你忘了调用image.UnlockBits(bitmapData);