2010-01-05 5 views
6

Programımın temel olarak bellek sızıntısı hakkında bir soru göndermedim: bkz. here. Özel olarak, bir Bitmap nesnesinin ham baytlarını yönetilen bir diziye kopyaladığım bazı kodları izledim. İlgili kod:Ham bitmap verilerinden yönetilen diziye Marshal.Copy'nin güvenli kullanımı

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); 
    } 
} 

Yani kurtarıldı olan bellek değil neden olan tüm kod kapsamını şu, ben kabul rağmen bunu Marshal.Copy() ile bir ilgisi vardır hayal olduğunu beri bir Bitmap'ten (kendi başına mı?) yönetilen bir diziye kopyalanıyordu, sorun yoktu.

Soru: Bitmap nesnesini ya IDisposable arabiriminden ya da benzer bir şeyden temizlemek gerekiyor mu? Bu durumda (eğer bir şey varsa), bu durumda Marshal.Copy() kullanımı ile doğal olarak yanlıştır ve sorunu nasıl temizleyebilirim? başında

Bitmap bmp = new Bitmap(1000, 1000); 
for (int n = 0; n < 100; ++n) 
{ 
    FastBitmap fb = new FastBitmap(bmp); 
} 

ve bu dizinin genel bellek sonu:

ben gerçekten buna neden sorun olduğunu doğrulamak için, aşağıdaki kodu test ettik Bilesin ki size

ederiz kullanım ne kadar sürdüğüne bakılmaksızın 320mb gibi bir şey tarafından artmış ve gitmez.

cevap

8

image.UnlockBits (bitmapData) öğesini çağırmayı unuttun;

+1

Teşekkürler, saatlerce hayal kırıklığı ve bunun kadar basit. – DeusAduro

+0

Bu makaleden, ikinci kod snippet'i, 'UnlockBitmap' işlevini (' UnlockBits' olarak adlandırır) özlüyorsunuz gibi görünüyor: http://www.devx.com/webdev/Article/44658/1763/page/2 – rwong