Ed *_* S. 32 .net c# wpf memory-leaks memory-management
好吧,这是我第一次尝试内存分析.NET应用程序(我已经完成了CPU调优),我在这里遇到了一些障碍.
我在我的应用程序中有一个视图,每页加载40个图像(最大),每个运行大约3MB.最大页数为10.由于我不想一次保留400张图像或1.2GB内存,因此在更改页面时将每个图像设置为空.
现在,起初我认为我必须对这些图像进行过时的引用.我下载了ANTS profiler(伟大的工具BTW)并进行了一些测试.对象生命周期图表告诉我,除了父类中的单个引用之外,我没有对这些图像的任何引用(这是设计的,也通过精心梳理我的代码来确认):
父类SlideViewModelBase
永远存在于缓存中,但是MacroImage
当页面更改时,属性设置为null.我没有看到任何迹象表明这些物体应该保持比预期更长的时间.
我接下来看一下大对象堆和内存使用情况.在查看三页图像后,我分配了691.9MB的非托管内存和LOH上的442.3MB. System.Byte[]
来自我System.Drawing.Bitmap
的BitmapImage
转换,几乎占据了所有的LOH空间.这是我的转换代码:
public static BitmapSource ToBmpSrc( this Bitmap b )
{
var bi = new BitmapImage();
var ms = new MemoryStream();
bi.CacheOption = BitmapCacheOption.OnLoad;
b.Save( ms, ImageFormat.Bmp );
ms.Position = 0;
bi.BeginInit();
ms.Seek( 0, SeekOrigin.Begin );
bi.StreamSource = ms;
bi.EndInit();
return bi;
}
Run Code Online (Sandbox Code Playgroud)
我很难找到所有非托管内存的去向.我System.Drawing.Bitmap
起初怀疑这些物体,但是ANTS并没有显示它们在附近,我也进行了一次测试,我确保所有这些都被处理掉了,并没有什么区别.所以我还没有弄清楚所有非托管内存的来源.
我目前的两个理论是:
如果有人有任何理论或剖析技巧,我将非常感激,因为(当然)我们正处在一个紧迫的期限内,我正在争先恐后地完成最后一部分工作.我认为通过追踪C++中的内存泄漏已经被宠坏了......谁会想到?
如果您需要更多信息或希望我尝试别的,请询问.对于这里的墙上文字感到抱歉,我尽量保持简洁.
Opp*_*nal 35
这篇博文似乎描述了你所看到的内容,建议的解决方案是创建一个包含另一个流的Stream实现.
此包装类的Dispose方法需要释放包装的流,以便可以对其进行垃圾回收.一旦使用此包装器流初始化BitmapImage,就可以释放包装器流,释放底层流,并允许释放大字节数组本身.
BitmapImage保留对源流的引用,以使MemoryStream对象保持活动状态.不幸的是,即使已经调用了MemoryStream.Dispose,它也不会释放内存流包装的字节数组.因此,在这种情况下,位图是引用流,它引用缓冲区,这可能占用大对象堆上的大量空间.没有真正的内存泄漏; 当没有更多对位图的引用时,所有这些对象将(最终)被垃圾收集.但由于位图已经制作了自己的图像私有副本(用于渲染),因此将现在不必要的位图原始副本仍然存储在内存中似乎相当浪费.
另外,您使用的是什么版本的.NET?在.NET 3.5 SP1之前,存在一个已知问题,即BitmapImage可能导致内存泄漏.解决方法是在BitmapImage上调用Freeze.
归档时间: |
|
查看次数: |
8232 次 |
最近记录: |