【问题标题】:Memory leak in loading an image C#加载图像C#中的内存泄漏
【发布时间】:2017-05-10 18:58:41
【问题描述】:

我编写了一个代码来将图像加载到<image> 控件中,并且由于我需要编辑和保存在多个地方使用的相同图像,因此我可以修改代码以避免Access violation error。现在我收到Out of memory exception

    private BitmapSource LoadImage(string path)
    {
        lock (_syncRoot) //lock the object so it doesn't get executed more than once at a time.
        {
            BitmapDecoder decoder = null;

            try
            {
                //If the image is not found in the folder, then show the image not found.
                if (!File.Exists(path) && (path != null))
                {
                    using (var stream = new System.IO.MemoryStream())
                    {
                        if (!File.Exists(Path.GetTempPath() + "ImageNotFound.jpg"))
                        {
                            System.Drawing.Bitmap ss = Ashley.ProductData.MarketSeries.Presentation.Properties.Resources.ImageNotFound;

                            using (FileStream file = new FileStream(Path.GetTempPath() + "ImageNotFound.jpg", FileMode.Create, FileAccess.Write))
                            {
                                ss.Save(stream, ImageFormat.Jpeg);
                                stream.Position = 0;
                                stream.WriteTo(file);
                            }
                        } 
                    }

                    path = Path.Combine(Path.GetTempPath(), "ImageNotFound.jpg");
                    NoImage = false;
                }
                else
                {
                    if (!EnableForEdit)
                        NoImage = false;
                    else
                        NoImage = true;
                }

                if (!string.IsNullOrEmpty(path) && (!NoImage || File.Exists(path)))
                {
                    using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read))
                    {
                        decoder = BitmapDecoder.Create(stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
                        return decoder.Frames.FirstOrDefault();
                    }

                }
                else
                    return null;
            }
            catch (OutOfMemoryException ex)
            {
                MessageBox.Show("Insufficient memory to handle the process. Please try again later.", "Application alert");                    

                return null;
            }
            catch (Exception ex)
            {
                // Error handling.
                 ShowMessages.AlertBox(ex.Message, MethodInfo.GetCurrentMethod().Name);
                throw ex;
            }
            finally
            {
                decoder = null;
            }
        }
    }

我需要知道上述代码中是否存在内存泄漏,或者是否有更好的方法来加载符合我要求的图像。

【问题讨论】:

    标签: wpf image image-processing memory-leaks bitmap


    【解决方案1】:

    该代码不应导致泄漏。但是您应该考虑是否要冻结图像。 x.ImageSource.Freeze();

    In what scenarios does freezing wpf objects benefit performace greatly

    此外,如果您认为您有内存泄漏,您应该使用分析器。 红蚂蚁的profiler救了我几十次Red Ant's .Net Memory Profiler

    说真的,这是值得的,他们可能有免费试用或其他东西,但它可以找到许多泄漏源,如计时器、未正确关闭的事件等。非常有帮助。如果您不喜欢它们,请寻求其他解决方案,但如果您寻找泄漏 Visual Studio 对您没有帮助,您需要一个 3rd 方解决方案。

    【讨论】:

      【解决方案2】:

      我遇到了类似的问题,并通过像这样加载图像来解决,

      //代码:

      替换,

       using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read))
           {
              decoder = BitmapDecoder.Create(stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
              return decoder.Frames.FirstOrDefault();
           }
      

      与,

        BitmapImage bi = new BitmapImage();
        bi.BeginInit();
        bi.CacheOption = BitmapCacheOption.OnLoad;
        bi.UriSource = new Uri(path);
        bi.EndInit();
        bi.Freeze();
        return bi;
      

      如果需要,在您的 finally 块中创建 bi 对象 null

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-12-15
        • 2017-01-27
        • 2016-08-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多