How to free the memory after the BitmapImage is no longer needed?

后端 未结 4 781
悲哀的现实
悲哀的现实 2020-11-30 07:12

First, I load a BitmapImage on the Image control on the Window. Second, I work with the Image control and then close the

4条回答
  •  时光取名叫无心
    2020-11-30 07:27

    In my situation it seems that the bitmap caching was the issue. I was previously loading bitmaps like this:

    Bitmap bitmap = new Bitmap();
    
    using(var stream = new FileStream(...))
    {
        bitmap.BeginInit();
        bitmap.CacheOption = BitmapCacheOption.OnLoad;
        bitmap.StreamSource = stream;
        bitmap.EndInit();
    }
    
    bitmap.Freeze();
    image.Source = bitmap;
    

    Continuously replacing image.Source the same way just built up memory, manually forcing garbage collection wasn't really helping.

    Instead, disabling the caching and having it use the stream (requires leaving the stream open until the image is displayed) paired with manual garbage collection eliminated memory build up for me.

    Stream mediaStream;
    
    void DisposeMediaStream()
    {
        if (mediaStream != null)
        {
            mediaStream.Close();
            mediaStream.Dispose();
            mediaStream = null;
            GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true);
        }
    }
    
    void Update()
    {
        DisposeMediaStream();
    
        var bitmap = new BitmapImage();
        mediaStream = new FileStream(...);
    
        bitmap.BeginInit();
        bitmap.CacheOption = BitmapCacheOption.None;
        bitmap.StreamSource = mediaStream;
        bitmap.EndInit();
    
        bitmap.Freeze();
        ControlImage.Source = bitmap;
    }
    

    This way I can cycle through tons of images (like Windows Photo Viewer) and memory stays low. Note that the stream does not have to stay open once the image has actually rendered.

提交回复
热议问题