首页 > 数据库技术 > 详细

浅谈windbg定位内存问题

时间:2019-08-22 00:20:50      阅读:163      评论:0      收藏:0      [点我收藏+]

 

背景

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


1.首先需要工具:windbg,以及出现问题时候的dump文件(用任务管理器 or DebugDiag抓取dump文件),

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

2.打开windbg,加载dump文件

3.进入命令阶段:

(1) 加载SOS CLR dll文件

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

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

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

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

技术分享图片

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

 

SOS 的语法是 :![command] [options]

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

(2) 显示关于垃圾收集堆的信息和有关对象的收集统计

使用命令:!dumpheap -stat

技术分享图片

技术分享图片

以上命令输出的第一列是mt(method table)信息,表示类型对象的地址。我们可以使用此信息来明确指定我们感兴趣的对象在堆中的信息.
看到上面的数据,我们想这些大的块,现在是正在被引用还是已经不被引用了呢?上面显示的是所有堆的整体占用信息,其实我们比较关心的是还被引用的对象信息。
!dumpheap -dead -min 85000 参数-dead:仅输出已死亡的对象 (这些对象将在下一个 Full GC 中被回收)

技术分享图片

以上结果显示:00000004b06ad190与00000004802fef20现在都是已经死亡的对象,在下一个Full GC中将被回收。
通理,!dumpheap -live -min 85000 现在还被引用的仍然存活的对象:

技术分享图片

查看其中占24M的数据对象,发现竟然是log的存储,天了噜!

技术分享图片

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

场景1:

选择查看StaffDto数据:!DumpHeap -mt 000007fe9ba5eba0

技术分享图片

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

!dumpobj 000000038a71b7f0

技术分享图片

打印EEClass结构,其中可以看到类型静态变量信息,可以根据MT信息查询其中的字段信息
看看里面的字段吧,!do 000000038a71ba60 (Email)

技术分享图片

然后输入:!gcroot 000000038a71ba60,看看其引用根:

技术分享图片

!gcroot 000000038a71b7f0 用来查看其中某一个的引用根信息:

我擦,竟然没有引用根。
说明:!gcroot是一个非常有用的命令,它能够帮助我们发现某对象上目前还存在的有效引用,这也是为什么GC还不回收这个对象的原因。这个信息可以很好的帮助我们分析那些本应该没有引用,但却一直还存在有效引用的对象,由此发现我们代码中潜在的内存泄漏,同时我们也可以观察到哪些对象是目前没有引用了。

场景2:

同理,查看多租赁的数据:
!DumpHeap -mt 000007fe9bfd6d70

技术分享图片

场景3:

查看string类型的数据:
!dumpheap -mt 000007fef828da88

 技术分享图片

string类型的数据个数180W,占用222M内存

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

技术分享图片

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

重点观察这两个string类型

!dumpobj 00000004b06ad190 (等价于!do)

技术分享图片

然后输入:!groot 00000004b06ad190 

技术分享图片

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

看看这个对象内容吧,dc 00000004b06ad190 L1000

 技术分享图片

技术分享图片

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

 

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

浅谈windbg定位内存问题

原文:https://www.cnblogs.com/walt/p/11391664.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!