2010-01-05 11 views
6

Przedtem napisałem pytanie o to, w jaki sposób mój program był zasadniczo nieszczelny w pamięci: zobacz here. Teraz śledziłem go specjalnie do jakiegoś kodu, w którym kopiuję surowe bajty obiektu Bitmap do zarządzanej tablicy. Odpowiedni kod:Bezpieczne korzystanie z Marshal.Copy z surowych danych bitmapowych do zarządzanej tablicy

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

Więc to wszystko zakres kodu, który powoduje pamięci nie są odzyskiwane, a ja sobie wyobrazić, że to ma coś wspólnego z Marshal.Copy() choć przypuszczałem, że skoro kopiował z Bitmapy (oczyszczonej samodzielnie?) do zarządzanej tablicy, nie było problemu.

Pytanie więc: czy konieczne jest oczyszczenie obiektu bitmapowego za pomocą interfejsu IDisposable lub czegoś podobnego. Co (jeśli coś jest) jest z natury niewłaściwe w użyciu Marshal.Copy() w tej sytuacji i gdzie mogę posprzątać ten problem?

Dziękuję

Tak wiesz ja testowałem poniższy kod, aby sprawdzić, czy rzeczywiście jest to przyczyną problemu:

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

Na początku i końca tej sekwencji ogólna pamięci wykorzystanie zwiększyło się o około 320 MB i nie zniknie, niezależnie od tego, jak długo czekasz.

Odpowiedz

8

Zapomniałeś zadzwonić image.UnlockBits (bitmapData);

+1

Wielkie dzięki, godziny frustracji i tak proste. – DeusAduro

+0

Wygląda na to, że brakuje Ci drugiego fragmentu kodu, funkcji "UnlockBitmap" (która nazywa się "UnlockBits"), z tego artykułu: http://www.devx.com/webdev/Article/44658/1763/page/2 – rwong

Powiązane problemy