.Net 内存对象分析

在生产环境中,经过运行日志咱们会发现一些异常问题,此时,咱们不能直接拿VS远程到服务器上调试,同时日志输出的信息没法百分百反映内存中对象的状态,好比说咱们想查看进程中全部的Socket链接状态、服务路由信息等等。windows

即:如何分析.Net 运行时内存对象?缓存

因此,今天咱们推荐.Net进阶必备神器:Windbg,基于Windbg分析内存中对象的状态。服务器

仍是以实际场景为例吧,这样能够更加贴合实际应用,同时更有借鉴意义。网络

业务场景:分布式环境下,各个服务容器进程中缓存了各个服务的Socket链接信息,方便运行时服务间相互访问。可是网络是偶尔要抖动的,在抖动的一瞬间,不少Socket链接便中断了,服务调用方收到的异常信息即是:链接已中断等。编辑器

如何快速定位到哪些Socket链接是中断的?这些中断的Socket链接是链接的哪些服务器、端口?这些信息能够帮助咱们分析具体的网络问题,同时作一些程序上的补偿:链接重建。一个目标,保持程序的高可用性!分布式

那么,请出咱们今天的主角:Windbg,微软的官方介绍:工具

http://windbg.org/spa

进一步说,咱们须要抓取指定进程某一瞬间的内存镜像,而后使用Windbg分析内存中各类对象、线程、线程池、析构队列、堆、CPU内核时间片等的状态。操作系统

所以,第一步,咱们须要对要进行内存分析的进程,抓取一个Full Dump文件:内存镜像文件。线程

任务管理器->选择进程->建立转储文件

系统会将Dump文件存储在指定的目录,这个目录须要拷贝一下,以备用。

第二步,从下面路径下载并安装Windbg

https://developer.microsoft.com/en-us/windows/hardware/download-windbg

请根据操做系统的位数,选择X86或者X64。这里咱们用的64位操做系统,选择的Windbg(X64)

第三步:Ctrl+D,打开刚才抓取的Dump文件

第四步:加载调试用的SOS.dll: .loadby sos clr

.loadby sos clr

第五步:查看内存中指定类型的对象 

!dumpheap -Type Socket

这里的Socket是具体的类型,咱们要查看Socket链接状态,因此类型是Socket

这里的Header中MT=Method Table

咱们须要用的MT:00007ffafe50d700

第六步,查看内存全部全部的Socket对象的地址:

!dumpheap -mt 00007ffafe50d700

 

输出结果中,第一列是某一个Socket对象的内存地址

此时,咱们可使用下面的命令,随机查看一个Socket对象的信息:

!do 000001b2d188ae00

!do 的意思:!dumpObj 

 那么问题来了,几百个Socket对象,若是一个一个!do查看,这工做量太大了! 固然不能这么干,Windbg有.foreach命令

 搜索Debugging help.chm文档,.foreach给了个样例:

.foreach /f ( place "g:\myfile.txt") { dds place } 

即,循环遍历一个文本文件,对每一行数据,执行一个命令操做。

好,咱们回到咱们上一步的输出中:每一个Socket对象的地址列表,咱们拷贝出来,用文本编辑工具只取出第一列(Socket地址列),保存成1.txt

第七步:循环遍历查看每一个内存对象

.foreach /f (adr "C:\1.txt") {!do adr}

输出:

将全部的输出,拷贝到文本编辑器中,搜索查询指定的属性,例如m_IsConnected=0, 便可找出链接断开的Socket对象,而后进一步用!gcroot 查看这个对象的引用关系,再一步一步看各个引用对象的信息就能够大体分析了。

 

以上就是.Net 内存对象分析的整个过程,分享给你们。

 

周国庆

2017/10/06

相关文章
相关标签/搜索