【问题标题】:c# Image loader memory leakc# 图像加载器内存泄漏
【发布时间】:2015-08-21 15:34:11
【问题描述】:

我正在实现一个小型图像查看器,不幸的是我正面临内存泄漏。 以下是我的加载程序。

 public BitmapSource getImage(string fileName, double width, double height)
    {
        FileStream s = File.Open(fileName, FileMode.Open);
        Image i = Image.FromStream(s, false, false);
        double iWidth = i.Width;
        double iHeight = i.Height;
        i.Dispose();
        s.Close();

        BitmapImage tmpImage = new BitmapImage();
        tmpImage.BeginInit();
        tmpImage.CacheOption = BitmapCacheOption.OnLoad;
        tmpImage.UriSource = new Uri(fileName);
        if (iWidth > iHeight)
        {
            tmpImage.DecodePixelWidth = (int)width;
        }
        else
        {
            tmpImage.DecodePixelHeight = (int)height;
        }
        tmpImage.EndInit();
        return tmpImage;
    }

这就是我调用加载器的方式

private void whenArrowKeyPressed(int index)
{
   CurrentImage =  fh.getImage(fileList[index], 1920, 1080);
}

CurrentImage 是一个属性,它绑定到 WPF ViewBox。

有什么想法吗? 我也尝试从 StreamSource 读取,效果相同。

【问题讨论】:

  • 您没有处理 FileStream。调用 s.Dispose() 而不是 s.Close(); Dispose 也会处理关闭。
  • 谢谢,我可以看到一些改进。不幸的是,它并没有完全解决问题。显示第一张图像时,应用程序使用 ca. 150MB,经过多次切换,我现在看到加到 ca,300MB
  • 我认为您的问题一定出在您尚未发布的某些代码中。我在您发布的代码中没有发现任何其他错误。
  • 顺便说一句,您可能想阅读以下内容:stackoverflow.com/questions/9175755/…
  • 谢谢。我也会检查剩余的代码。

标签: c# image memory-leaks bitmapimage


【解决方案1】:

我能看到的唯一问题是您没有处理 FileStream。 BitmapImage 不是 Disposable,如果没有对其的引用,它将释放其内存。

您是如何发现内存泄漏的?建议使用分析工具。垃圾收集器不会立即释放内存超出范围,它会等到内存使用量超过某些阈值(通常是在 Gen 0 超过阈值时)。因此,您会看到一些内存增加,并且只有在垃圾收集器执行后才会释放内存。

显然您没有使用分析工具。在这种情况下,如果您想检查是否有任何内存泄漏,您可以手动执行 GC.Collect 并等待最终确定,然后再读取内存。请记住,您不必手动执行 GC.Collect,因为它会在需要时以优化的方式自动发生。

    public BitmapSource getImage(string fileName, double width, double height)
    {
        using(FileStream s = File.Open(fileName, FileMode.Open))
        using(Image i = Image.FromStream(s, false, false))
        {
            double iWidth = i.Width;
            double iHeight = i.Height;                
        }

        BitmapImage tmpImage = new BitmapImage();
        tmpImage.BeginInit();
        tmpImage.CacheOption = BitmapCacheOption.OnLoad;
        tmpImage.UriSource = new Uri(fileName);
        if (iWidth > iHeight)
        {
            tmpImage.DecodePixelWidth = (int)width;
        }
        else
        {
            tmpImage.DecodePixelHeight = (int)height;
        }
        tmpImage.EndInit();
        return tmpImage;
    }

private void whenArrowKeyPressed(int index)
{
   CurrentImage =  fh.getImage(fileList[index], 1920, 1080);

   // Remove this once you finish testing.
   GC.Collect();
   GC.WaitForPendingFinalizers();
}

【讨论】:

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