1. 背景

在开发过程中,我们可能遇到应用程序线程占用过大的问题,可以通过windbg命令去定位哪些类型,哪些内存一直占用堆资源,从而查出问题,解决问题。

2. 准备工作

工具:

  • 抓取DUMP文件的工具,任务管理器(最简单),DebugDiag,ProcessExplorer等(网上很多)
  • 分析工具windbg

PS:使用任务管理器的时候需要强调一下如何抓包:根据你的进程是多少位的,然后使用对应位数的任务管理器去抓,

不然抓到的DUMP文件是无效的。

如果在下面分析过程中出现“SOS does not support the current target architecture”这样的错误,就是使用了64位的

任务管理器导出了32位进程的dump文件,下面是两个解决方法:
(1)使用32位任务管理器,运行:C:\Windows\SysWOW64\taskmgr.exe。
(2)使用其它转储工具,比如:ProcessExplorer。

3. 分析

抓取DUMP文件后,使用windbg工具打开,首先加载SOS.dll,CLR.dll文件。

备注:SOS是啥东西?SOS可以调试扩展,让你可以查看在CLR里面运行的代码的有关信息。

例如,你可以使用SOS调试扩展显示托管堆的有关信息,查找堆的错误,显示运行时使用的内部数据类型,

以及查看在运行时里面运行的所有托管代码的有关信息。

相关参考:https://www.cnblogs.com/ceachy/p/WinDBG_SOS.html

备注:以上加载sos.dll与clr.dll的时候可能报错,上面截图的错误是说你使用的dll版本与当前的windbg分析的DUMP文件位数不一致

(1) 加载SOS&CLR

在加载sos.dll与clr.dll的时候,首先你要确定你的DUMP文件的位数,如果是32位则可以使用如下方式加载:

.load C:/Windows/Microsoft.NET/Framework/v4.0.30319/sos.dll
.load C:/Windows/Microsoft.NET/Framework/v4.0.30319/clr.dll

如果是64位,则使用另外的加载方式:

.load C:/Windows/Microsoft.NET/Framework64/v2.0.50727/sos.dll
.load C:/Windows/Microsoft.NET/Framework64/v4.0.30319/sos.dll

  

其中,SOS 的命令格式 :![command] [options]

具体参考:https://www.cnblogs.com/kissdodog/p/3731743.html

(2)使用命令!dumpheap -stat 显示关于垃圾收集堆的信息和有关对象的收集统计:

图3-1

图3-2

以上命令执行后,输出结果的第一列是mt(method table)信息,表示类型对象的地址,我们可以使用此信息来明确指定我们感兴趣的对象在堆中的信息。

看到上面的数据,我们这些占用内存比较大的对象,此时有没有被引用?上面显示的是所有堆的整体占用信息,其实我们比较关心的还是被引用的对象的信息。

使用命令:!dumpheap -dead -min 85000  参数 -dead:表示仅输出没有没有被引用的对象 (这些对象将在下一个 Full GC 中被回收);

-min 85000 :表示查看大于85000bytes字节的对象

命令执行后发现:00000004b06ad190(占用48M)与00000004802fef20(占用49M)这两个对象都没有被引用了(挑了两个占用大的),那么 这些对象将在下一个Full GC中被回收。

相反,使用命令:!dumpheap -live -min 85000 查看的是还被引用的对象:

根据分析结果可以看出,占用比较大的是0000000484884750(占用24M),我们使用命令:!do 0000000484884750 

查看一下这个对象到底是何方妖孽:

上图的结果显示:其中占24M的数据对象,发现竟然是log的存储,天了噜!

这样不行,从图3-1中,再挑选一个业务性比较强的类型看看。

场景1:

选择查看StaffDto数据,首先还是执行命令:!DumpHeap -mt 000007fe9ba5eba0 查看显示有关垃圾收集堆和收集站的信息

以上命令输出第一列是Address,表示具体数据的地址,从上面可以看到这个StaffDto对象共有58515个,然后占堆内存30M,拿其中某一个看看

!dumpobj 000000038a71b7f0

打印EEClass结构,其中可以看到类型静态变量信息,可以根据MT信息查询其中的字段信息

看看里面的字段吧,!do 000000038a71ba60 (Email)

然后输入命令:!gcroot 000000038a71ba60(!gcroot 命令是用来查看其中某一个对象的引用根信息),看看其引用根:

我晕,竟然没有引用根。

备注:!gcroot是一个非常有用的命令,它能够帮助我们发现某对象上目前还存在的有效引用,这也是为什么GC还不回收这个对象的原因。

这个信息可以很好的帮助我们分析那些本应该没有引用,但却一直还存在有效引用的对象,

由此发现我们代码中潜在的内存泄漏,同时我们也可以观察到哪些对象是目前没有引用了。

场景2:

我们选择图3-2中最后那个string类型的对象数据:

!dumpheap -mt 000007fef828da88

结果分析发现:string类型的数据个数180W,占用222M内存,这也不用大惊小怪,代码程序中使用频繁的对象应该就是string了,接着往下看。

!dumpheap -mt 000007fef828da88 -min 85000 // 查看85K以上的string类型数据

命令执行结果显示:大于85K的string对象有8个,占98M,其中两个分别是42M与48M

那就重点观察这两个string类型的对象,使用命令

!dumpobj 00000004b06ad190 (等价于!do)

然后紧接着去分析这个对象的引用根信息,输入命令:!groot 00000004b06ad190 

这个对象竟然也没有有效引用根???

看看这个对象内容吧,使用命令:dc 00000004b06ad190 L1000(命令dc是查看对象内容,参数L代表显示多少行)

以上结果显示,这个48M的string内容是存的staffDto信息。

以上就是我根据网上的教程,然后拿着自己在服务器dump下来的文件进行的内存分析,windbg这个工具真的很锻炼人,慢慢从头学起吧!与君共勉~

使用windbg定位内存问题【入门级】的更多相关文章

  1. 强大的windbg定位内存泄露,两句命令搞定!

    1.简单配置在windbg程序目录下有个gflags.exe,运行后设置: 运行CMD.EXE,输入"D:\Debugging Tools for Windows (x86)\gflags. ...

  2. umdh windbg分析内存泄露

    A.利用工具umdh(user-mode dump heap)分析:此处以程序MemoryLeak.exe为例子 1.开启cmd 键入要定位内存泄露的程序gflags.exe /i memroylea ...

  3. FastMM 定位内存泄露的代码位置

    FastMM 定位内存泄露的代码位置 开源的FastMM,使用很简单,在工程的第一行引用FastMM4即可(注意,一定要在第一个Uses的位置),可以在调试程序时提示内存泄露情况,还可以生成报告. 在 ...

  4. 利用linux的mtrace命令定位内存泄露(Memory Leak)

    一谈到内存泄露, 多数程序猿都闻之色变. 没错, 内存泄露非常easy引入. 但非常难定位.  以你我的手机为例(如果不常常关机). 如果每天泄露一些内存, 那么開始的一个星期, 你会发现手机好好的. ...

  5. VS2015 定位内存泄漏工具vld

    介绍一款在vs2015开发环境定位内存泄漏工具:Visual Leak Detector ,具体的使用方法如下: 1.  安装vld-2.5-setup.exe (下载链接地址后面会给出),安装过程会 ...

  6. C++程序在Windows平台上各种定位内存泄漏的方法,并对比了它们的优缺点

    一.前言 在Linux平台上有valgrind可以非常方便的帮助我们定位内存泄漏,因为Linux在开发领域的使用场景大多是跑服务器,再加上它的开源属性,相对而言,处理问题容易形成“统一”的标准.而在W ...

  7. 记一次使用windbg排查内存泄漏的过程

    一.背景 近期有一个项目在运行当中出现一些问题,程序顺利启动,但是观察一阵子后发现内存使用总量在很缓慢地升高, 虽然偶尔还会往下降一些,但是总体还是不断上升:内存运行6个小时候从33M上升到80M: ...

  8. WinDBg定位asp.net mvc项目异常崩溃源码位置

    项目介绍:asp.net mvc + angular +iis(windows)+windows server 系统莫名崩溃 最近有个系统默认奇妙崩溃50x,服务整体变成无响应,当运维告知我只有重启应 ...

  9. 【linux】linux下对java程序生成dump文件,并使用IBM Heap Analyzer进行分析,查找定位内存泄漏的问题代码

    1.首先,java程序启动在linux,怎么生成dump文件? 1>第一步,首先你需要得到java程序的PID,最简单的方法使用如下命令 ps -ef|grep java 或者如果是docker ...

随机推荐

  1. 【poj 3090】Visible Lattice Points(数论--欧拉函数 找规律求前缀和)

    题意:问从(0,0)到(x,y)(0≤x, y≤N)的线段没有与其他整数点相交的点数. 解法:只有 gcd(x,y)=1 时才满足条件,问 N 以前所有的合法点的和,就发现和上一题-- [poj 24 ...

  2. bfs输出路径 && 最短路(迪杰斯特拉)输出路径

    问题描述 解决方法 1.像第一个问题那就是最短路问题(我代码采用迪杰斯特拉算法)实现 2.换乘次数最少,那就用bfs广搜来寻找答案.但是我的代码不能保证这个最少换乘是最短路程 代码 1 #includ ...

  3. 在kubernetes集群里集成Apollo配置中心(5)之dubbo服务消费者连接apollo实战

    1.在Apollo的portal创建dubbo消费者项目 (1)添加dubbo消费者项目 (2)在dubbo消费者项目中添加配置项 (3)发布 2.通过jenkins构建dubbo消费者镜像 3.登录 ...

  4. 使用SignTool对软件安装包进行数字签名(二)--进行数字签名

    四.使用signcode.exe为安装程序.库或cab包签名 1.运行signcode.exe. 2.点击"下一步",选择需要签名的文件(安装程序.库或cab包). 3.点击&qu ...

  5. 使用DTK创建模糊背景窗口并自定义阴影效果

    DTK是deepin开发的基于Qt的开发套件,提供了大量的具有独特风格的美化控件,也提供了很多非常方便的API,下边我们用DTK实现一个模糊窗口,并设置其阴影效果. 使用场景 一切需要模糊窗口作为美化 ...

  6. 逆元 exgcd 费马小定理 中国剩余定理的理解和证明

    一.除法取模逆元 如果我们要通过一个前面取过模的式子递推出其他要取模的式子,而递推式里又存在除法 那么一个很尴尬的事情出现了,假如a[i-1]=100%31=7 a[i]=(a[i-1]/2)%31 ...

  7. JSON简单理解

    JSON 与 JS 对象的关系 很多人搞不清楚 JSON 和 Js 对象的关系,甚至连谁是谁都不清楚.其实,可以这么理解: JSON 是 JS 对象的字符串表示法,它使用文本表示一个 JS 对象的信息 ...

  8. 如何使用 js 实现相似图片搜索

    如何使用 js 实现相似图片搜索 以图搜图 https://www.google.com/imghp?hl=en https://www.google.com/imghp?hl=zh https:// ...

  9. Node.js _dirname & path All In One

    Node.js _dirname & path All In One file path 相对路径 绝对路径 _dirname https://nodejs.org/docs/latest/a ...

  10. HTTPS in depth

    HTTPS in depth HTTPS Hypertext Transfer Protocol Secure How does HTTPS work? https://www.cloudflare. ...