图像的 WPF 内存问题

Tsu*_*asa 5 c# wpf

我似乎遇到了一些大的内存消耗问题。当我第一次加载包含 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;
Run Code Online (Sandbox Code Playgroud)

然后被分配给 Image.Source

mar*_*mnl 2

以下是一些提示和猜测,但是如果您使用内存分析器,您将能够看到占用内存的内容。(例如CLR 分析器VS 2012 和 2013 也提供内置内存分析工具,以及其他商业工具:.NET 内存分析工具


  • 为什么你CacheOption BitmapCacheOption.None这里指定说:

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

相反,你可以使用OnLoad

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

我的理解是:如果您在许多位置显示图像,它们共享相同的底层内存。因此,如果您在多个地方显示同一张图像,那肯定会更好。

  • 在此处示例的评论中找到的另一个提示:

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

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