近期有一个项目在运行当中出现一些问题,程序顺利启动,但是观察一阵子后发现内存使用总量在很缓慢地升高,
虽然偶尔还会往下降一些,但是总体还是不断上升;内存运行6个小时候从33M上升到80M;
程序存在内存泄漏是确定无疑的了,大概出问题的方向也知道,就是程序新加入一个采集协议(BACnet协议,MSTP_DLL),
但是怎么把具体泄漏位置找出来却非常麻烦,因为这个协议是封装在一个C语言写的动态库中,想要单步调试好像不太可能,
况且源码也不再我这里;
如果到此为止,推脱给其他同事找问题,那联合调试费时不说。其他同事也身兼数职,不大可能有时间调试,
那项目推进肯定停滞;那没办法了,只能硬着头皮上;网上了解一番,对于这种内存泄漏问题,比较好的处理方式就是
抓取内存快照,然后分析数据提交记录,使用查看使用堆栈等信息;所以基于以上原因,选择了windbg内核调试工具;
先分析一下看看,说不定可以发现问题;
二、windbg注意事项
1、首先要安装对版本,即你的程序是32位还是64位,对于的windbg版本也要一致,否则会报错;详情了解:点击这里
2、需要用64位的任务管理器抓32位的dump文件,那不能直接在任务管理器右键“创建转储文件“,需要运行(C:\Windows\SysWOW64\taskmgr.exe)
3、或者直接在windbg上使用命令存储,先附件到进程,然后使用命令:(.dump /ma c:\xxx.dmp),这样就将快照保存在C盘了;
4、最重要的,要确保你的机器能连接外网;由于windbg的使用需要在线更新符号文件,但是这个地址刚好被国家防火墙屏蔽;
三、windbg必要设置
1、首先我先抓取2个内存快照文件(中间相隔一段时间),如下
2、打开windbg,设置符号下载路径
将33.dmp直接拖进工作区即可,然后打开菜单File -> Symbol File Path
输入地址:SRV*c:\symbols*
四、分析文件
1、分别打开两个dmp文件,输入命令!dumpheap -stat查看各种类型的内存分配情况
33.dmp
>.load C:\Windows\Microsoft.NET\Framework\v4.0.30319\SOS.dll
>!dumpheap -stat
.....
61f87928
2292
34012 System.RuntimeType[]
5d2dbe74
267
34176 System.Data.DataColumn
61fd75e0
668
37408 System.Reflection.RuntimePropertyInfo
61f8426c
702
48976 System.Int32[]
5d2dcc24
70
72520 System.Data.RBTree`1+Node[[System.Data.DataRow, System.Data]][]
61f883e4
1242
84456 System.Reflection.RuntimeParameterInfo
61f8839c
2045
89980 System.Signature
0a7566bc
596
92976 HG.MacamUnit.Entity.TSubSysNodes
61f82788
723
117736 System.Object[]
61f89850
8
131696 System.Int64[]
61fd8938
2792
167520 System.Reflection.RuntimeMethodInfo
007988d0
220
434392
Free
61f824e4 12187
738904 System.String
61f85c40
2138
743067 System.Byte[]
61f82c60
294
6629796 System.Char[]
Total 55014 objects