你如何确保WPF释放大量的BitmapSource从记忆? [英] How do you make sure WPF releases large BitmapSource from Memory?

查看:369
本文介绍了你如何确保WPF释放大量的BitmapSource从记忆?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

系统:Windows XP SP3,.NET 3.5,4GB内存,双1.6GHz的

System: Windows XP SP3, .NET 3.5, 4GB RAM, Dual 1.6gHz

我有负载和过渡(用故事板动画)非常大的PNG WPF应用程序。这些PNG图像在分辨率8190x1080。当应用程序运行时出现缓存图像和系统内存慢慢爬行。最后,它扼流圈系统并引发OutOfMemoryException异常。

I have a WPF application that loads and transitions (using Storyboard animations) extremely large PNGs. These PNGs are 8190x1080 in resolution. As the application runs it appears to cache the images and the system Memory slowly creeps up. Eventually it chokes the system and throws the OutOfMemoryException.

下面是我目前正在设法解决这个问题的步骤:

Here are the steps I am currently taking to try to solve this:

1)我是从应用程序删除的BitmapSource对象

1)I am removing the BitmapSource objects from the app

2)我设置的BitmapSource BitmapCacheOption为无,当我加载的BitmapSource

2)I am setting the BitmapSource BitmapCacheOption to None when I load the BitmapSource

3)我冻结的BitmapSource一旦它的加载。

3)I am Freezing the BitmapSource once it's loaded.

4)我删除到使用源以及对源本身。

4)I am deleting all references to the Image that uses the source as well as any references to the source itself.

5)手动调用GC.Collect的()以上步骤完成之后。

5)Manually calling GC.Collect() after above steps have completed.

希望能弄清楚为什么WPF是挂到存储这些图像和可能的解决方案,以确保内存使用的加载它们正确地恢复。

Hoping to figure out why WPF is hanging onto memory for these images and a possible solution to ensure that the memory used to load them is properly recovered.

推荐答案

您肯定已经投入了大量的工作这一点。我认为主要的问题是,BitmapCacheOption.None没有prevent被缓存的底层BitmapDe codeR(S)。

You certainly have put in a lot of work on this. I think the main problem is that BitmapCacheOption.None doesn't prevent the underlying BitmapDecoder(s) from being cached.

有作为再次做GC.Collect的(),装载300不同的URI 300的小图片,并调用所以GC.Collect()这个这样几个棘手的解决方案,但简单的是直接的:

There are several tricky solutions to this such as doing a GC.Collect(), loading 300 small images from 300 different Uris, and calling GC.Collect() again, but the simple one is straightforward:

而不是从一个URI加载的,只是构建一个流,并将其传递给BitmapFrame的构造函数:

Instead of loading from a Uri, just construct a Stream and pass it to BitmapFrame's constructor:

var source = new BitmapImage();
using(Stream stream = ...)
{
  source.BeginInit();
  source.StreamSource = stream;
  source.CacheOption = BitmapCacheOption.OnLoad;    // not a mistake - see below
  source.EndInit();
}

这应该工作的原因是从流装车完全禁用缓存。不仅是顶层源没有缓存,但没有内部解codeRS要么被缓存。

The reason this should work is that loading from a stream completely disables the cache. Not only is the top-level source not cached, but none of the internal decoders are cached either.

为什么BitmapCacheOption.OnLoad?似乎违反直觉,但这种标志有两个作用:它使缓存如果缓存是可能的,它会导致负载在EndInit在发生()。在我们的例子缓存是不可能的,因此,所有这不会造成负荷立即发生。

Why BitmapCacheOption.OnLoad? It seems counterintuitive, but this flag has two effects: It enables caching if caching is possible, and it causes the load to happen at EndInit(). In our case caching is impossible, so all it does it cause the load to happen immediately.

显然,你要运行这个code关闭UI线程,则冻结的BitmapSource以便您可以通过移动它。

Obviously you'll want to run this code off your UI thread, then freeze the BitmapSource so you can move it over.

您也可能想知道为什么我没有用BitmapCreateOptions.IgnoreImageCache。除了一个事实,即缓存是不可能的,没有给定URI的IgnoreImageCache并不完全忽略图像缓存:它只忽略它的阅读。因此,即使IgnoreImageCache设置,加载的图像仍然插入到高速缓存中。所不同的是在高速缓存中已有的图像将被忽略。

You may also wonder why I didn't use BitmapCreateOptions.IgnoreImageCache. Other than the fact that caching is impossible any with no URI given, the IgnoreImageCache doesn't completely ignore the image cache: It only ignores it for reading. So even if IgnoreImageCache is set, the loaded image is still inserted into the cache. The difference is that the existing image in the cache is ignored.

这篇关于你如何确保WPF释放大量的BitmapSource从记忆?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆