【问题标题】:WPF memory issue with images图像的 WPF 内存问题
【发布时间】:2013-12-18 05:07:04
【问题描述】:

我似乎遇到了一些大的内存消耗问题。当我第一次加载包含 gridview 和 observablecollection 的 wpf 应用程序时,该应用程序的大小约为 10mb。

当我点击 gridview 中的一个项目时,它会打开另一个窗口,其中包含一个图像控件,该控件传递一个 base64 字符串,然后我将其转换为 BitmapImage

然后应用程序从 10mb 跃升至 123mb 左右。原始图像大小为 64k,但我存储的所有图像都是 base64 字符串,我将其转换回 byte[],然后转换为 BitmapImage。 是的,我的意思是这样做。

当我关闭窗口时,没有一个 ram 被释放。我什至尝试过调用 GC。

我用下面的代码把base64图片转成

var bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.CacheOption = BitmapCacheOption.None;
bitmapImage.StreamSource = new SIO.MemoryStream(imageBytes);
bitmapImage.EndInit();
return bitmapImage;

然后将其分配给 Image.Source

【问题讨论】:

  • 这听起来像是一个分析工作。
  • 如果您将 CacheOption 更改为 BimapCacheOption.OnLoad,您会发现有什么不同吗?还要检查你没有挂在imageBytes的副本上。

标签: c# wpf


【解决方案1】:

以下是一些提示和猜测,但是如果您使用内存分析器,您将能够看到占用内存的内容。 (例如the CLR profiler also VS 2012 ad 2013 come in-built memory profile tools,以及其他商业的:.NET Memory Profiling Tools


  • 为什么要指定CacheOption BitmapCacheOption.None from here 说:

不要创建内存存储。所有对图片的请求都直接由图片文件填充。

你可以使用OnLoad:

在加载时将整个图像缓存到内存中。所有对图像数据的请求都从内存存储中填充。

我的意思是:如果您在多个位置显示图像,它们共享相同的底层内存。因此,如果您在多个地方展示同一张图片,那肯定会更可取。

  • 在示例 here 的 cmets 中找到的另一个提示:

要节省大量应用程序内存,请设置 DecodePixelWidth 或
图像源的BitmapImage值的DecodePixelHeight到想要的 渲染图像的高度和宽度。如果您不这样做,应用程序将 缓存图像,就好像它被渲染为其正常大小而不是仅仅 显示的尺寸。

  • 你为什么使用 base64 字符串,为什么不使用二进制数据,即byte[]s?您引用了每个字符串的多少个副本?

【讨论】:

  • 感谢分析器为我指明了正确的方向,现在我的 ram 使用量从 123mb 降至 25mb 左右,这是合理的。
  • @Tsukasa,我很好奇,有什么问题?
  • 它实际上与我正在研究的一个加密类有关,但我忘记了我正在调用它。这就是吃公羊的原因,因为它没有释放物体。我不知道分析工具。我想我需要从现在开始养成使用它们的习惯。
【解决方案2】:

同意 BitMap 不会释放它的内存(尝试并厌倦了内存泄漏)。 但是试试这个link

阅读最后一条评论可能是这种解决方法可能会解决问题

【讨论】:

    猜你喜欢
    • 2011-03-23
    • 2013-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多