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.
Wielkie dzięki, godziny frustracji i tak proste. – DeusAduro
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