wpf 内存泄漏调查

大约花了三天的时间,心态一度炸裂~ 特来总结一下寻找的过程。(ps:现在在听 四季予你,全靠网易云救命)

安装文件+下载教程:链接: https://pan.baidu.com/s/1eLqtiS2eVMnyTubFehWwtw 提取码: 4yif 复制这段内容后打开百度网盘手机App,操作更方便哦

整体描述: 测试说: 不行啊,跑了3天多崩了,前台内存涨到700多MB(正常就200MB)

一、查找问题

1.首先去找程序运行时的log文件,好死不死log中关于内存的记录出了问题,没办法只能改好后再花时间再跑一次,这次直接用VS和内存检测工具 ANTS Memory Profiler 8一起跑,

内存检测工具 ANTS Memory Profiler 8 (它的使用方式有官网教程):

链接: https://pan.baidu.com/s/1oy5zIe0nbFlNV_kYmusiZQ

提取码: v55w   

在这里要注意下,就像我们调试服务一样,有一些需要附加进程的进程这么是看不出来的。需要我们用这个工具的附件进程功能(这个在主页面上不能看非托管内存,但是里面可以)

2.经过录制我就得到了下面的数据,可以看画线的部分,代表从 01:17到04:18这4分钟内,内存增长了16.14MB。而我们的UnmanagedMemoryStream增长了14MB,就确定这个罪魁祸首了。

UnmanagedMemoryStream这种非托管内存 一般是不能呗GC回收的,所以这玩意就很恶心,得先找到他在看具体的代码。通常来说 这种问题在c#中最可能就是,在c#中使用了指针但是没有像c++那样使用完自己释放。可以现在代码中找这种代码 IntPtr ptr = Marshal.AllocHGlobal(704* 576 * 3); 调用Marshal.AllocHGlobal必须调用 Marshal.FreeHGlobal(ptr)

在这里总结一下非托管内存泄露的几种可能: GUI+,图片,文件操作,win32。Stream流之类的。还有本次的主角 wpf 数据binding,textBlock 字体引用非绝对路径后,频繁赋值不会释放得问题。

3.知道内存原因是因为UnmanagedMemoryStream这个后,就一分钟的截取快照实例,关注它得增长,发现它一直在增长。

4.它一直在增长就说明他是个循环,是一直在循环东西。这时候就可以把当前页面上功能拆分来看,这样很容易就能找到具体的模块。通过这种思路找到了最源头得一句代码

            _dispatcher.InvokeAsync(() =>
            {

                    UpdateTimeStamp = DataTime.Now.ToString(); //就是wpf 最简单得bingding数据。40毫秒一刷新
            });

5.上面代码是简写,测试后发现不涨内存得情况有两种:1.界面上不显示这个值,也就是在textblock上不绑定这个值,但是这个值还在后台一直变化。2.给这个给值赋一个固定的值,例如”00“

这样就表明是数据bingding出了问题,这个textblock值改变后一直没有释放资源。找了资料发现 只要是字体的资源是相对路径引用的,textblock就不会释放内存,导致UnmanagedMemoryStream增加。

(在嵌套控件中发生。为啥也不是很清楚。。。。)

修改方法:1.换了个窗体单独显示这个控件。2. 绑定了一个 系统自带的字体。

注意:textbox有一中缓存机制,TextBoxBase.UndoLimit设置成0(或者把IsUndoEnabled设置成False),也就是命令TextBox不支持撤销功能。(大量修改)

bingding 的时候 如果没有引用 INotifyPropertyChanged,这个大家应该都不会忘记。


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部