WPF致命泄露bug!有没有!

superzmy凄临雨 2011-03-31 12:04:51
相信用过WPF的BitmapImage的,都在用类似这样的代码来解决文件无法删除的问题!
[size=9px]
static class AppHelper
{
public static BitmapImage GetBitmapImage(string path)
{
BitmapImage bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.StreamSource = new MemoryStream(File.ReadAllBytes(path));
bitmap.EndInit();
bitmap.Freeze();
return bitmap;
}
}[/size]
但是就算这样也只是解决了文件独占的泄露问题,开你的任务管理器看看吧
内存只占用不释放
for(int i = 0; i < 20; i++)
{
AppHelper.GetBitmapImage("Images/img003.bmp");
}
上面代码里面的bmp有4MB大,循环过后没有持有图像的引用,但是内存占用不断增大,根本无法下降

然后想跟我说Dispose、Using、Close的童鞋们好好看清楚BitmapImage这个类根本就没有IDispose接口,也没有提供Close方法
想不到WPF最基础的图像类有内存泄露bug吧!
...全文
723 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
fancystyle 2011-07-26
  • 打赏
  • 举报
回复
我提交了一个BUG.如果大家有这个问题.也顶一下吧.

https://connect.microsoft.com/WPF/feedback/details/680742/bitmapimage-does-not-release-memory-leak-in-wpf4
fancystyle 2011-07-21
  • 打赏
  • 举报
回复
顶上来.我觉得是个WPF 的BUG
xant111 2011-07-19
  • 打赏
  • 举报
回复
结果没明白啊,还是没办法释放资源是吧?我现在很苦恼这个问题
superzmy凄临雨 2011-05-31
  • 打赏
  • 举报
回复
再测试排除上面的推测,无法重现问题
superzmy凄临雨 2011-05-31
  • 打赏
  • 举报
回复
过了许久到了今天,我换了SSD硬盘,无意中再测试发现没有内存泄露,所以现在怀疑可能是windows的superfetch功能自动缓存图片文件导致的bug
机器人 2011-03-31
  • 打赏
  • 举报
回复
机器人 2011-03-31
  • 打赏
  • 举报
回复
关注。。。

在这篇msdn blog中提到了WPF应用容易发生内存泄露的几种case,其中提到了BitmapImage。
但里面也提到了解决办法,lz可以参考下:

http://blogs.msdn.com/b/jgoldb/archive/2008/02/04/finding-memory-leaks-in-wpf-based-applications.aspx

比如:
来自静态的资源,这里提到用Freeze()方法避免内存泄露
bi1 =  new BitmapImage(new Uri("Bitmap1.bmp",UriKind.RelativeOrAbsolute));
//if you do not Freeze, your app will leak memory
bi1.Freeze() m_Image1 = new Image();
m_Image1.Source = bi1;
MyStackPanel.Children.Add(m_Image1);
superzmy凄临雨 2011-03-31
  • 打赏
  • 举报
回复
为了进一步排除MemoryStream的影响,我用一个静态变量MemoryStream缓存掉了每次都创建的流
现在发现任务管理器里面内存占用量确实是少了一半
但是仍然的,存在着和图像文件大小正相关的内存泄露!
superzmy凄临雨 2011-03-31
  • 打赏
  • 举报
回复
根据以上的回复,我把函数稍作修改
public static BitmapImage GetBitmapImage(string path)
{
BitmapImage bitmap = new BitmapImage();
bitmap.CreateOptions = BitmapCreateOptions.None;
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.BeginInit();
bitmap.StreamSource = new MemoryStream(File.ReadAllBytes(path));
bitmap.EndInit();
bitmap.Freeze();
bitmap.StreamSource.Dispose();
return bitmap;
}
就算这样的代码,产生的BitmapImage对象已经没办法显示出来
它仍然占用了内存并且不予释放
superzmy凄临雨 2011-03-31
  • 打赏
  • 举报
回复
没有用的,就算我直接把StreamSource对象Dispose,内存占用都不会下降
泄露的内存并不是来自StreamSource!
  • 打赏
  • 举报
回复
如果看看msdn上简单的描述,可以看到这样的说明:


如果 StreamSource 和 UriSource 均设置,则忽略 StreamSource 值。

如果要在创建 BitmapImage 后关闭流,请将 CacheOption 属性设置为 BitmapCacheOption.OnLoad。 默认 OnDemand 缓存选项保留对流的访问,直至需要位图并且垃圾回收器执行清理为止。
superzmy凄临雨 2011-03-31
  • 打赏
  • 举报
回复
目前的想法是用反射来调用私有方法和成员,把里面的资源释放掉
superzmy凄临雨 2011-03-31
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 laputa_island 的回复:]
引用 3 楼 sp1234 的回复:
如果看看msdn上简单的描述,可以看到这样的说明:


如果 StreamSource 和 UriSource 均设置,则忽略 StreamSource 值。

如果要在创建 BitmapImage 后关闭流,请将 CacheOption 属性设置为 BitmapCacheOption.OnLoad。 默认 OnDemand 缓存选项保留对流的访问……
[/Quote]
????
子夜__ 2011-03-31
  • 打赏
  • 举报
回复
然后想跟我说Dispose、Using、Close的童鞋们好好看清楚BitmapImage这个类根本就没有IDispose接口,也没有提供Close方法

假如BitmapImage有Dispose的话 也就跟image的Dispose一样吧?

LZ你看看
这篇文章
superzmy凄临雨 2011-03-31
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 juqiang 的回复:]
http://code.logos.com/blog/2008/04/memory_leak_with_bitmapimage_and_memorystream.html

自己做一个wrapper,对memorystream的包装
[/Quote]

1.文中提到“Note that there isn't a true memory leak”
但是在我的实验中他们一直都没有被引用,所以这是真的true momery leak
该不被释放的还是不被释放
2.虽然我没有做这个wrapper,但是我共享streambuffer以后,内存占用量只是减少,但没有达到比不做循环读图片只多出几个MB的水平(多用了30MB,不共享streambuffer的情形多用了50~60MB的范围),所以做warpper的效果也不能真正解决
Laputa_Island 2011-03-31
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 superzmy 的回复:]
我只能证明有这个bug存在,但是修复它不是我的责任……
微软该打补丁了……我用的不是4.0SP1么……
[/Quote]
... ..LZ英明。。LZ千秋万代,一统江湖
Laputa_Island 2011-03-31
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 sp1234 的回复:]
如果看看msdn上简单的描述,可以看到这样的说明:


如果 StreamSource 和 UriSource 均设置,则忽略 StreamSource 值。

如果要在创建 BitmapImage 后关闭流,请将 CacheOption 属性设置为 BitmapCacheOption.OnLoad。 默认 OnDemand 缓存选项保留对流的访问,直至需要位图并且垃圾回收器执行清理为止……
[/Quote]
哎。。 。。。
juqiang 2011-03-31
  • 打赏
  • 举报
回复
http://code.logos.com/blog/2008/04/memory_leak_with_bitmapimage_and_memorystream.html

自己做一个wrapper,对memorystream的包装
superzmy凄临雨 2011-03-31
  • 打赏
  • 举报
回复
我只能证明有这个bug存在,但是修复它不是我的责任……
微软该打补丁了……我用的不是4.0SP1么……
superzmy凄临雨 2011-03-31
  • 打赏
  • 举报
回复
BitmapImage泄露其实是非托管资源的泄露
GC拿他没办法的

17,740

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 .NET Framework
社区管理员
  • .NET Framework社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧