博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
通过分析内存来优化.NET程序
阅读量:6608 次
发布时间:2019-06-24

本文共 2536 字,大约阅读时间需要 8 分钟。

最近在做一个MSMQ的Agent服务,在这里分享一下这个服务在优化的一点经验,通过分析内存更准确地定位出程序中存在的性能问题,从而让程序的性能以倍数的提升.

问题的引发

由于通过.NET MSMQ的Client实现消息分布和故障转移实在测试效果并不理想..所以决定实现一个MSMQ的Agent服务,由于有网络编写的经验所以对实现的效果还有很有信心的.可惜最终实现出来的效果实在惨不忍睹...4个连接并发消息写入只有150/秒,实在是完全坑爹的结果!在架构上的设计并不存在问题,所以问题一定存在程序实现过程中,以往的经验告诉自己做内存分析是最直接的办法.

问题排查一Buffer没正常回收到Pool

由于在测试过程CPU使用率并不高,所以怀疑是Buffer没有回收到Pool导致

从分析的结果来说,的确是自己在写代码的时候犯错了...存在大量的buffer被Pop出来导致大量内存被创建.但从代码流程上来看找不到任何原因.

public override void MessageWrite(IMessage msg, BufferWriter writer)        {            HttpData hb = msg as HttpData;              try            {                using (hb.Message)                {                    msg.Save(writer);                }            }            finally            {                                if (hb != null)                {                    hb.Message = null;                    HttpDataPackage.HttpDataPool.Push(hb);                }            }        }

分析结果已经说明了问题所在,所以调试了一下程序,发现问题的根源是HttpData的Message为空,但using不会报错坑爹啊...

public void ToProtocolData(HttpData httpbase)        {            httpbase.Action = Action;            httpbase.Message = this;            OnToProtocolData(httpbase);            ;        }

适当地修改一处程序问题解决.

吐能力提高但CPU占用资源过高

经过上面程序的修复4连接的秒吞吐能力由原来每秒150左右,上升到每秒2100/秒.得到的效果是非常的明显的,但总的来说CPU占用资源还有点过高,为了验证上一次修复的问题又进行了一次内存分析,分析的结果如下:

分析说明了一个问题由于Assembly.GetName()导致了大量的string创建,代码如下:

value = string.Format("{0},{1}={2}", type.FullName, type.Assembly.GetName().Name, JsonConvert.SerializeObject(Message));

适当地修改一下

value = string.Format("{0}={1}", GetTypeName(type), JsonConvert.SerializeObject(Message));        private static System.Collections.Hashtable mNames = new System.Collections.Hashtable(1024);        private static string GetTypeName(Type type)        {            string name = (string)mNames[type];            if (name == null)            {                lock (mNames)                {                    name = (string)mNames[type];                    if (name == null)                    {                        name = string.Format("{0},{1}", type.FullName, type.Assembly.GetName().Name);                        mNames[type] = name;                    }                }            }            return name;        }

经过以上的进一步优化后,服务的效果算是比较理想,完全满足了现阶段的需要.

意外的发现

从测试分析的结果看来,Newtonsoft.Json这个组件还有针对性优化的空间

针对以上分析,Newtonsoft.Json存在的问题应该如何优化,那就要留大家思考了.

总结

其实很多朋友喜欢通过CPU计时来看程序的快慢,但得到的结果只能说明问题,但对于如何解决这些问题,测试运行时间的结果似乎起不到什么作用.其实.NET程序有一个东西往往没有得到关注,MS在一些文档中要强调我们没有必要关心,这个东西其实就是GC!的确我们对GC的工作直接可控性是没有,但有一点可以肯定的就是GC的工作由对象的创建导致,如果想控制GC我们最好是从设计层面上控制对象的创建,这是最直接有效的办法.

转载地址:http://ywiso.baihongyu.com/

你可能感兴趣的文章
sed的基本用法
查看>>
一个不错的shell 脚本入门教程
查看>>
Ansible之playbook的使用
查看>>
ansible模块批量管理
查看>>
redis命令 - GET
查看>>
httpd.conf的基本设置
查看>>
RHEL/Centos7新功能
查看>>
DBA日常工作职责
查看>>
Redis的持久化
查看>>
linux安装NFS服务器学习
查看>>
Planner .NET日历日程控件能给你的应用程序提供多种日历日程功能
查看>>
我的友情链接
查看>>
Linux压力测试
查看>>
JAVA中的线程机制(二)
查看>>
nginx安装与配置2(转载)
查看>>
沈阳一饭店凌晨爆燃,燃气报警器时刻预防
查看>>
Redis 与 数据库处理数据的两种模式
查看>>
VUE2中axios的使用方法
查看>>
CS 229 notes Supervised Learning
查看>>
2018.10.27-dtoj-3996-Lesson5!(johnny)
查看>>