none
WPF展示图片时,内存要如何才能释放? RRS feed

  • 问题

  • 首先,加载一张图片代码如下:

             string path = wnd.FileName;
                    using (var ms = new System.IO.MemoryStream(File.ReadAllBytes(path)))
                    {
                        BitmapImage bitmap = new BitmapImage();
                        bitmap.BeginInit();
                        bitmap.StreamSource = ms;
                        bitmap.CacheOption = BitmapCacheOption.OnLoad;
                        bitmap.EndInit();
                        mainImg.Source = bitmap;
                    }

    图片文件是一张1M左右的图片,加载之后内存激增30M左右!为什么多出这么多?

    然后我将图片控件的资源释放代码如下

    mainImg.Source = null;

    但是内存占用没有丝毫减少,即便我加入了GC强制回收

    GC.Collect();

    内存占用少了一点点,但是还是75M左右,这么回事呢?我要如何才能让他释放掉占用的内存?

    之所以做这个小测试,是因为我的界面上要显示很多图片,然后就内存溢出了......

    2016年3月25日 9:09

答案

  • 你好 坚强的贝壳,

    你遇到的场景是一个已知的问题中的一个, 下面的MSDN Blog罗列出了这些场景和解决办法,详情参考下面的文章。

    #Memory Leaks in WPF based applications – Blog Update

    https://blogs.msdn.microsoft.com/jgoldb/2008/05/05/memory-leaks-in-wpf-based-applications-blog-update/ 


    static BitmapImage bi1 = new BitmapImage(new Uri("Bitmap1.bmp",
    UriKind.RelativeOrAbsolute));
    static BitmapImage bi2 = new BitmapImage(new Uri("Bitmap2.bmp",
    UriKind.RelativeOrAbsolute));
    bi2.Freeze();
    m_Image1 = new Image();
    //bi1.Freeze() //even though you are really using bi2 for Image Source, you also need to Freeze bi1 it to avoid leak 
    m_Image1.Source = bi1;  // use un-frozen bitmap, which causes the leak
    m_Image1.Source = bi2;  // use frozen bitmap
    MyStackPanel.Children.Add(m_Image1);
    希望能够帮你解决问题。


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2016年3月28日 2:26
    版主
  • ?????
    • 已标记为答案 坚强的贝壳 2016年3月29日 1:03
    • 已编辑 [-] 2018年1月11日 13:22
    2016年3月28日 9:39

全部回复

  • 你好 坚强的贝壳,

    你遇到的场景是一个已知的问题中的一个, 下面的MSDN Blog罗列出了这些场景和解决办法,详情参考下面的文章。

    #Memory Leaks in WPF based applications – Blog Update

    https://blogs.msdn.microsoft.com/jgoldb/2008/05/05/memory-leaks-in-wpf-based-applications-blog-update/ 


    static BitmapImage bi1 = new BitmapImage(new Uri("Bitmap1.bmp",
    UriKind.RelativeOrAbsolute));
    static BitmapImage bi2 = new BitmapImage(new Uri("Bitmap2.bmp",
    UriKind.RelativeOrAbsolute));
    bi2.Freeze();
    m_Image1 = new Image();
    //bi1.Freeze() //even though you are really using bi2 for Image Source, you also need to Freeze bi1 it to avoid leak 
    m_Image1.Source = bi1;  // use un-frozen bitmap, which causes the leak
    m_Image1.Source = bi2;  // use frozen bitmap
    MyStackPanel.Children.Add(m_Image1);
    希望能够帮你解决问题。


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2016年3月28日 2:26
    版主
  • 非常感谢,这个解决了我内存释放的问题,请问你知道为什么显示一张1M的图片需要30多M的内存吗?

    如果这样子的话,同时展示多张图片是需要的内存就是一个很吓人的事情啊!

    2016年3月28日 3:45
  • ?????
    • 已标记为答案 坚强的贝壳 2016年3月29日 1:03
    • 已编辑 [-] 2018年1月11日 13:22
    2016年3月28日 9:39
  • 感谢,目前我采用的方式还是缩略图啊,点击的时候查看原图,要不然内存真心伤不起。。。
    2016年3月29日 1:05
  • 1M是编码后大小,显示是需要解码的,解码后就大了。
    2018年9月10日 2:29