加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

记一次C#的内存优化过程

(2010-09-02 11:38:23)
标签:

杂谈

            服务端是WCF,客户端是一个CS程序,快完工的时候发现有内存增长的情况,如果放一晚上的话,out of memory。。。。

           C#查内存没有C++那么直接,又实际上比C/C++方便,无他,有运行时吗,原来用过CLR profiler,内存不够看,放弃,下了.Net Memroy Profiler 试用版来干活,内存占用小了很多,功能强了很多,舒服,不过我可怜的2G内存还是不够看啊,跑了一晚上马上4G了,out of memory。。。。。残念

           打开Memory Profiler,新建一个工程,选好可执行文件,一路Next。然后启动profiler过程,傻瓜化。翻到RealTime页面,看全局内存。好吗,只涨不跌。股票要这样还差不离。内存吗,总不能指望谁都是Win7 X64外带24G DDR3套装,EVGA巨无霸主板,ATI 5970 SLI,六屏拼接,好了扯远了。。。。

    http://s10/middle/6d541f31492f7b0c15b19&690       

    Memory Profiler还是很好用的,启动后先做一个snapshot,就是那个照相机按钮,过一段时间,内存涨上来了,再做一次snapshot。然后切到Typs页面,showtypes设成With new or removed instances,这样可以看这段时间创建和销毁的对象了,按delta排一下序,ok。几分钟里面,string多了1.7w,xml多了5k,Servicemodal等等多了1-2k,靠,一共多出了14W个对象,这回事情大条了,我这满脑门子的汗那。。。。

http://s5/middle/6d541f31492f7b0df0ee4&690

     这个时候选中一个双击,比如string,切换到详细界面了,sort stack by 选中New Live Instances,大概遍历一下最近新创建的对象都有哪些,CallStack都有,很容易的,如果时长太长就放短点做snapshot,只有几十个的时候比较好分辨哪些对象没释放,我这里找出来的居然是WCF,WCF啊WCF内存泄露,真是怕什么来什么。为了定制一些feature,我们的WCF客户端用了一堆自定义的东西,基本不依靠MS那套配置文件。大家都是第一次WCF,内存出问题,大家只好悲剧了,查吧。

http://s16/middle/6d541f31492f7b0b04b1f&690

      最后定位是建立WCF连接时出了问题,为了自定义messageheader,屏蔽MS那套配置文件,WCF连接全是自己写代码做的,不是MS工具生成的代理类。过程大概是自己生成binding,channelfactory,改了endpoint的一个behavior,塞了用户名和key在messageheader里面做状态维护啥的。查了半天资料,原来channelFactory,IContextChannel和OperationContextScope全部都需要手工dispose,所以在伟大的Timer的领导下,我们的内存以每5s一次的速度快速增长着,快赶上GDP的速度了。恩,冥思苦想N小时,做了个泛型包装类把WCF连接加个个壳(第一次用C#泛型,虽然功能比C++弱,但是易用不少),重构的结果是减少了几百行代码,赞,顺带感谢using{}语法。然后内存就如下图了。虽然不平滑吧,但是有涨有跌,终于淡定了,内存么,浮云。。。。

http://s11/middle/6d541f31492f7b0eb06ca&690

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有