BitmapImages release used as an image control source (memory issue)

I have a simple WPF window with and below the Image control. When the user moves the slider, I download and set various images as the image source. I got quite a few images from 200 KB in size, but when I move this slider back and fourth, the program starts to eat quite a lot of memory. Hundreds and hundreds of megabytes of memory. Most of them receive garbage collected ultimately, but not all.

Maybe WPF is not the way, or should I force G / C? I tried to load the image as a bitmap and get the source of the bitmap using Imaging.CreateBitmapSourceFromHBitmap() and Win32-api to delete and delete, etc., but I'm just doing worse :)

I think I should try to grab the existing image source and somehow release it before downloading and assigning a new one.

Any ideas?

EDIT

I am adding some sample code that works fine and seems to keep memory low and thin:

  private Image _lastImage; // Event when user moves the slider control, load image using the filname in // the _images[] array which contains hundreds of images private void SliderChanged(object sender, RoutedPropertyChangedEventArgs<double> e) { if (_lastImage != null) _lastImage.Dispose(); var image = Image.FromFile(_images[(int)ImageSlider.Value]); Snapshot.Source = ImageToBitmapImage(image); _lastImage = image; } private static ImageSource ImageToBitmapImage(Image image) { BitmapImage bitmapImage; using (var ms = new MemoryStream()) { image.Save(ms, ImageFormat.Jpeg); bitmapImage = new BitmapImage(); bitmapImage.BeginInit(); bitmapImage.StreamSource = new MemoryStream(ms.ToArray()); bitmapImage.EndInit(); } return bitmapImage; } 
+3
source share
3 answers

Forcing the GC collection is really terrible. Instead, call the .Dispose() method of the Bitmap object, what is it there for!

0
source
  • The method you use (Imaging.CreateBitmapSourceFromHBitmap ()) is unmanaged and may require you to manually .Dispose ().
  • WPF allows you to load a bitmap through a given URI: see http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.bitmapimage.aspx
  • GC will take care of collecting any managed objects (for example, using BitmapImage).
  • You may be loading too many images into memory. the original images accumulate memory quite quickly (a 1024x786 image with 32-bit color takes about 3 MB of RAM). GC must work very hard to clear them. You can reduce the size of the image after loading (reduce it) and use less memory
  • Finally, the GC does not guarantee that all memory will be released after the GC cycle. These are promises "best effort." although it usually calls GC.Collect (0); will lead to a full GC cycle and will release almost everything that can be released.
0
source

Have you tried the new BitmapCache class in .NET 4? This may solve your problem.

0
source

Source: https://habr.com/ru/post/976250/


All Articles