猿问

.NET内存加载约40张图像时出现问题,未回收内存,可能是由于LOH碎片导致

好吧,这是我第一次尝试对.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 ++中的内存泄漏已使我宠坏了……谁会想到?


如果您需要更多信息或希望我尝试其他事情,请询问。对不起这里的贴图文字,我试图尽量保持简洁。


神不在的星期二
浏览 630回答 3
3回答
随时随地看视频慕课网APP
我要回答