.Net 内存对象分析

发表于:2017-10-10 11:28

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:Eric zhou    来源:博客

  在生产环境中,通过运行日志我们会发现一些异常问题,此时,我们不能直接拿VS远程到服务器上调试,同时日志输出的信息无法百分百反映内存中对象的状态,比如说我们想查看进程中所有的Socket连接状态、服务路由信息等等。
  即:如何分析.Net运行时内存对象?
  所以,今天我们推荐.Net进阶必备神器:Windbg,基于Windbg分析内存中对象的状态。
  还是以实际场景为例吧,这样可以更加贴合实际应用,同时更有借鉴意义。
  业务场景:分布式环境下,各个服务容器进程中缓存了各个服务的Socket连接信息,方便运行时服务间相互访问。但是网络是偶尔要抖动的,在抖动的一瞬间,很多Socket连接便中断了,服务调用方收到的异常信息便是:连接已中断等。
  如何快速定位到哪些Socket连接是中断的?这些中断的Socket连接是连接的哪些服务器、端口?这些信息可以帮助我们分析具体的网络问题,同时做一些程序上的补偿:连接重建。一个目标,保持程序的高可用性!
  那么,请出我们今天的主角:Windbg,微软的官方介绍:
  http://windbg.org/
  进一步说,我们需要抓取指定进程某一瞬间的内存镜像,然后使用Windbg分析内存中各种对象、线程、线程池、析构队列、堆、CPU内核时间片等的状态。
  因此,第一步,我们需要对要进行内存分析的进程,抓取一个FullDump文件:内存镜像文件。
  任务管理器->选择进程->创建转储文件
  系统会将Dump文件存储在指定的目录,这个目录需要拷贝一下,以备用。
  第二步,从下面路径下载并安装Windbg:
  https://developer.microsoft.com/en-us/windows/hardware/download-windbg
  请根据操作系统的位数,选择X86或者X64。这里我们用的64位操作系统,选择的Windbg(X64)
  第三步:Ctrl+D,打开刚才抓取的Dump文件

  第四步:加载调试用的SOS.dll:.loadbysosclr
  .loadbysosclr
  第五步:查看内存中指定类型的对象
  !dumpheap-TypeSocket
  这里的Socket是具体的类型,我们要查看Socket连接状态,所以类型是Socket
  这里的Header中MT=MethodTable
  我们需要用的MT:00007ffafe50d700
  第六步,查看内存所有所有的Socket对象的地址:
  !dumpheap-mt00007ffafe50d700
  输出结果中,第一列是某一个Socket对象的内存地址
  此时,我们可以使用下面的命令,随机查看一个Socket对象的信息:
  !do000001b2d188ae00
  !do的意思:!dumpObj
  那么问题来了,几百个Socket对象,如果一个一个!do查看,这工作量太大了!当然不能这么干,Windbg有.foreach命令
  搜索Debugginghelp.chm文档,.foreach给了个样例:
  .foreach/f(place"g:\myfile.txt"){ddsplace}
  即,循环遍历一个文本文件,对每一行数据,执行一个命令操作。
  好,我们回到我们上一步的输出中:每个Socket对象的地址列表,我们拷贝出来,用文本编辑工具只取出第一列(Socket地址列),保存成1.txt
  第七步:循环遍历查看每个内存对象
  .foreach/f(adr"C:\1.txt"){!doadr}
  输出:
  将所有的输出,拷贝到文本编辑器中,搜索查询指定的属性,例如m_IsConnected=0,即可找出连接断开的Socket对象,然后进一步用!gcroot查看这个对象的引用关系,再一步一步看各个引用对象的信息就可以大致分析了。
  以上就是.Net内存对象分析的整个过程,分享给大家。
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号