好吧,这是我第一次尝试对.NET应用程序进行内存配置(我已经完成了CPU调整),在这里我碰到了一些麻烦。
我的应用程序中有一个视图,该视图每页加载40张图像(最多),每张图像大约运行3MB。页面的最大数量为10。由于我不想一次在内存中保留400张图像或1.2GB,因此在更改页面时将每个图像设置为null。
现在,起初我以为我必须对这些图像有陈旧的引用。我下载了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;
}
我很难找到所有这些非托管内存的去向。System.Drawing.Bitmap起初我怀疑这些物体,但是ANTS并没有显示它们粘在周围,并且我还进行了一项测试,在此过程中,我完全确定所有物体都已处置并且没有任何影响。所以我还没有弄清楚所有这些非托管内存的来源。
我目前的两个理论是:
H碎片。如果我离开页面视图并单击几个按钮,则将回收大约1.5GB的一半。仍然太多,但是仍然很有趣。
WPF绑定有些奇怪。我们确实使用数据绑定来显示这些图像,并且我对这些WPF控件的工作原理一无所知。
如果有人有任何理论或分析技巧,我将非常感激,因为(当然)我们的截止日期很紧,我正在加紧努力以完成最后一部分并开始工作。我认为跟踪C ++中的内存泄漏已使我宠坏了……谁会想到?
如果您需要更多信息或希望我尝试其他事情,请询问。对不起这里的贴图文字,我试图尽量保持简洁。