dis*_*rax 14 wpf memory-leaks bitmap bitmapsource
系统:Windows XP SP3,.NET 3.5,4GB RAM,双1.6gHz
我有一个WPF应用程序加载和转换(使用Storyboard动画)非常大的PNG.这些PNG的分辨率为8190x1080.当应用程序运行时,它似乎缓存图像,系统内存缓慢爬升.最终它会阻塞系统并抛出OutOfMemoryException.
以下是我目前正在尝试解决此问题的步骤:
1)我从应用程序中删除BitmapSource对象
2)我在加载BitmapSource时将BitmapSource BitmapCacheOption设置为None
3)我在加载后冻结BitmapSource.
4)我将删除对使用源的Image的所有引用以及对源本身的任何引用.
5)完成上述步骤后,手动调用GC.Collect().
希望找出为什么WPF挂在这些映像的内存上,以及确保用于加载它们的内存得到正确恢复的可能解决方案.
Ray*_*rns 25
你当然在这方面做了很多工作.我认为主要问题是BitmapCacheOption.None不会阻止底层BitmapDecoder被缓存.
有几个棘手的解决方案,例如执行GC.Collect(),从300个不同的Uris加载300个小图像,再次调用GC.Collect(),但简单的解决方案很简单:
而不是从Uri加载,只需构造一个Stream并将其传递给BitmapFrame的构造函数:
var source = new BitmapImage();
using(Stream stream = ...)
{
source.BeginInit();
source.StreamSource = stream;
source.CacheOption = BitmapCacheOption.OnLoad; // not a mistake - see below
source.EndInit();
}
Run Code Online (Sandbox Code Playgroud)
这应该工作的原因是从流加载完全禁用缓存.顶级源不仅没有缓存,也没有内部解码器被缓存.
为什么BitmapCacheOption.OnLoad?这似乎违反直觉,但是这个标志有两个作用:如果可以进行缓存,它会启用缓存,并且它会导致在EndInit()中发生加载.在我们的例子中,缓存是不可能的,所以它只会导致负载立即发生.
显然,您需要从UI线程运行此代码,然后冻结BitmapSource,以便将其移动.
您可能也想知道为什么我没有使用BitmapCreateOptions.IgnoreImageCache.除了没有给出任何URI的高速缓存这一事实外,IgnoreImageCache不会完全忽略图像高速缓存:它只会忽略它以进行读取.因此,即使设置了IgnoreImageCache,加载的图像仍会插入缓存中.不同之处在于忽略缓存中的现有图像.
| 归档时间: |
|
| 查看次数: |
10558 次 |
| 最近记录: |