这篇主要讲如何分析高内存和高CPU。

1、如何分析高内存

注:如果抓Dump的同时,刚好在执行GC,抓出来的Dump执行命令多半会出错,用!VerifyHeap也能验证Dump有误,这种情况只能重新抓Dump。报错如下:

The garbage collector data structures are not in a valid state for traversal.

It is either in the "plan phase," where objects are being moved around, or

we are at the initialization or shutdown of the gc heap. Commands related to

displaying, finding or traversing objects as well as gc heap segments may not

work properly. !dumpheap and !verifyheap may incorrectly complain of heap

consistency errors.

Could not request method table data for object 6E8B4D74 (MethodTable: FFE00F74).

procdump -ma TranProc //用procdump工具抓dump,用windbg打开,加载sos扩展

!eeheap [-gc] [-loader] //可以先用这个初步判断一下是否确实有高内存,主要在哪里。一般LoaderHeap较小,问题多半出在GC Heap里。
Total LoaderHeap size: Size: 0x2f000 (192512) bytes.
=======================================
Number of GC Heaps: 1
generation 0 starts at 0x02d01018
generation 1 starts at 0x02d0100c
generation 2 starts at 0x02d01000
ephemeral segment allocation context: none
segment begin allocated size
02d00000 02d01000 02e99ff4 0x198ff4(1675252)
Large object heap starts at 0x03d01000
segment begin allocated size
03d00000 03d01000 03d12408 0x11408(70664)
Total Size: Size: 0x1aa3fc (1745916) bytes.
------------------------------
GC Heap Size: Size: 0x1aa3fc (1745916) bytes. !DumpHeap -stat //能看到占最大的对象是string,有143万个,占了171M内存
0x00007ffbae467df0 1,435,313 171,657,048 System.String
!DumpHeap -stat -gen 0 // -gen 参数只有psscor2里的DumpHeap才支持!
!DumpHeap -stat -gen 1
!DumpHeap -stat -gen 2 // 分别查看3个gen的统计情况,能看到主要集中在gen 2上,与perfmon显示的情况一致
!DumpHeap -stat -type System.String //针对这个类型做统计,也能看到类似的结果
MT Count TotalSize Class Name
0x00007ffbae467df0 1,435,313 171,657,048 System.String
Total 1,435,313 objects, Total size: 171,657,048 //现在的关键是:为什么程序会产生这么多string对象,并且没回收?谁(哪些对象)引用了这些string,然后在code里找到这些变量名,分析代码的写法是否有问题
!DumpHeap -type System.String
Address MT Size
02e928b8 6fbd2300 72
02e92900 6fbd2300 1168
可以找Size最大的几个对象,用!do 02e92900 查看这个对象为什么产生了这么多string。之后配合!gcroot 02e92900 看一下这个对象的根在哪里,为什么没回收。 !gcroot -mt 0x00007ffbae467df0 //在不知道对象实例,只知道对象类型的时候,用!gcroot -mt [MethodTable] 非常有用,能找到是哪些对象(包括<object address>,可以用!do、!DumpMT)创建了大量的目标对象(在这里是string),可惜不能统计出哪个Container里含有多少个目标对象。但可以看到引用链Reporter->Report->List<string>->object[],另一个引用链是AppDomain->AppDomainSetup->object[],问题当然出在我们的代码里,于是分析Reporter和Report的源码解决问题。如果没有dll,也可以SaveModule出来再用ILSpy打开。
Scan Thread 0 OSThread c10
RSP:cee858:Root: 0000000002b837c8(TranProc.Reporter)->
0000000002b83768(TranProc.Report)->
0000000002b83780(System.Collections.Generic.List 1[[System.String, mscorlib]])->
0000000013b85470(System.Object[])
……
Scan Thread 4 OSThread b90
rdx:Root: 00000000123de5f8(System.String)
r8:Root: 00000000123de5f8(System.String)
DOMAIN(0000000000E50EE0):HANDLE(Strong):213f8:Root: 0000000002b81478(System.AppDomain)->
0000000002b81560(System.AppDomainSetup)->
0000000002b815b0(System.Object[]) !do 0000000002b83768
Name: TranProc.Report
MethodTable: 00007ffb50dc3718
EEClass: 00007ffb50ef3640
Size: 24(0x18) bytes
GC Generation: 2
(D:\IT\debug\Exercise\Labdata\lab6\TranProc\Debug\TranProc.exe)
Fields:
MT Field Offset Type VT Attr Value Name
0000000000000000 4000007 8 0 instance 0000000002b83780 reportDetails //最后,可以通过SaveModule把dll保存出来仔细查看,通过这个过程,基本可以确定高内存的问题所在。
!SaveModule 00400000 d:\ProcessItems.dll

2、如何分析高CPU

高CPU,一般伴随着死锁或线程间同步问题。可以从下面对dump的分析,看出一些思路。

!syncblk  //可以看到ba8号线程持有一个锁AsyncRendering<EventHandlerObject>,地址为000000000559f920
Index SyncBlock MonitorHeld Recursion Owning Thread Info SyncBlock Owner
802 000000001e086658 11 1 000000000404cf30 ba8 10 000000000559f920 Microsoft.Windows.ManagementUI.CombinedControls.AsyncRendering+EventHandlerObject !threads //能观察到有2个Domain(406e3b0、40f8d10),每个分别有一个STA的UI线程
ID OSID ThreadOBJ State GC GC Alloc Context Domain Count APT Exception
0 1 10d8 0000000004076870 4220 Enabled 00000000057713c8:0000000005771430 000000000406e3b0 0 STA System.IO.FileNotFoundException (0000000005205eb0)
7 3 1e90 00000000040f25d0 2007020 Enabled 0000000005776a10:0000000005777430 00000000040f8d10 2 STA
10 6 ba8 000000000404cf30 380b220 Enabled 00000000056ee470:00000000056efb50 00000000040f8d10 2 MTA (Threadpool Worker)
~10s //进入10号线程
!clrstack //观察线程上的堆栈,看起来在等一个WaitHandle,其他也看不出什么了
000000001e97e760 000007feebb7250b System.Threading.WaitHandle.WaitOne(Int64, Boolean)
000000001e97e7a0 000007feeb537707 System.Windows.Forms.Control.WaitForWaitHandle(System.Threading.WaitHandle)
~7s //进入7号线程
!clrstack //都是MIGUIControls.dll里的代码,Save出来看看!
Microsoft.Windows.ManagementUI.CombinedControls.AsyncRendering.RenderValueInt(Microsoft.Windows.ManagementUI.CombinedControls.RenderingContext, Microsoft.Windows.ManagementUI.CombinedControls.RenderValueHandler, Boolean, System.String ByRef)
Microsoft.Windows.ManagementUI.CombinedControls.AsyncRendering.AddRenderingToBatch(Int32, Microsoft.Windows.ManagementUI.CombinedControls.RenderingContext, Microsoft.Windows.ManagementUI.CombinedControls.RenderValueHandler)
Microsoft.Windows.ManagementUI.CombinedControls.CrimsonEvent.GetEventMessage(Boolean, Microsoft.Windows.ManagementUI.CombinedControls.RenderValueHandler, Int32, Int32)
Microsoft.Windows.ManagementUI.CombinedControls.CrimsonEvent.GetMessage(Microsoft.Windows.ManagementUI.CombinedControls.RenderValueHandler, Int32, Int32) !runaway //看一下各线程执行时间,hang的问题要么是死锁、要么是无限循环?、要么是性能问题执行太慢?呵呵。结果表明7号线程执行的比较久, 10号持有锁
User Mode Time
Thread Time
7:1e90 0 days 0:00:02.090
0:10d8 0 days 0:00:00.733
10:ba8 0 days 0:00:00.655 !SaveAllModules d:\ //先把dll保存出来,总归是慢在用户自己的代码上面,应该就是这个MIGUIControls.dll,执行慢的7号线程、和持有锁的10号线程。具体问题如何分析,还需要总结经验。

windbg调试C#代码(二)的更多相关文章

  1. windbg调试C#代码(一)

    用windbg调试C#代码是比较麻烦的,因为windbg是针对OS层级的,而C#被CLR隔了一层,很多原生的命令如查看局部变量dv.查看变量类型dt等在CLR的环境中都不能用了.必须使用针对CLR的扩 ...

  2. 调试SQLSERVER (二)使用Windbg调试SQLSERVER的环境设置

    调试SQLSERVER (二)使用Windbg调试SQLSERVER的环境设置 调试SQLSERVER (一)生成dump文件的方法调试SQLSERVER (三)使用Windbg调试SQLSERVER ...

  3. 调试SQLSERVER (三)使用Windbg调试SQLSERVER的一些命令

    调试SQLSERVER (三)使用Windbg调试SQLSERVER的一些命令 调试SQLSERVER (一)生成dump文件的方法调试SQLSERVER (二)使用Windbg调试SQLSERVER ...

  4. 内核,配置WinDbg,调试操作系统(双机调试)

    配置WinDbg,调试操作系统(双机调试) PS: 设置双机调试之前,请先安装虚拟机,并且安装好XP系统.这里不做演示.直接设置. 一丶WinDbg的设置 1) 配置WinDbg的环境,在path变量 ...

  5. Windbg 脚本命令简介 二, Windbg command

    Windbg  脚本命令简介 二, Windbg  script command $<, $><, $$<, $$><, $$>a< (Run Scri ...

  6. windbg调试堆破坏

    堆破坏 所谓的堆破坏,是说没控制好自己的指针,把不属于你分配的那块内存给写覆盖了.这块内存可能是你程序的数据,也可能是堆的管理结构.那么这个会导致怎样的后果呢?可能的情况我们来yy下 把程序里的计算结 ...

  7. windbg调试托管代码 .Net clr

    现在很多的程序都是多语言混合编程的,比如我司的产品,就是用C++/.net clr混合编制的.那么当我们调试这样的程序时,一定要注意,比如有时我们只看到c++的栈和名称,而.net clr的代码确看不 ...

  8. .NET高级调试系列-Windbg调试入门篇

    Windbg是.NET高级调试领域中不可或缺的一个工具和利器,也是日常我们分析解决问题的必备.准备近期写2篇精华文章,集中给大家分享一下如果通过Windbg进行.NET高级调试. 今天我们来一篇入门的 ...

  9. 开源项目asmjit——调用自定义方法demo以及windbg调试

    asmjit是一个开源项目,使用它可以将代码即时的编译成机器码,也就是所谓的jit技术. 初次接触这个项目,编写了一个demo,学习它的使用方法. 现将编写的demo以及调试jit生成的机器码的过程总 ...

随机推荐

  1. [js] 跨域

    原文链接:http://www.cnblogs.com/scottckt/archive/2011/11/12/2246531.html 什么是跨域? 首先什么是跨域,简单地理解就是因为JavaScr ...

  2. 转:如何学习SQL(第四部分:DBMS扩展功能与SQL高级话题)

    转自:http://blog.163.com/mig3719@126/blog/static/285720652010950102575/ 9. DBMS提供的扩展功能 掌握了基本的关系模型原理和DB ...

  3. phalcon: Profiling分析 profilter / Plugin结合,dispatcher调度控制器 监听sql执行日志

    个人觉得profilter 跟 logger 功能差不多,logger的功能在于写入,profilter功能在于sql后及时显示分析.都是对sql执行的的分析:一个是写入log文件,一个是直接在页面展 ...

  4. Windows高精度时间

    目录 第1章计时    1 1.1 GetTickCount    1 1.2 timeGetTime    1 1.3 QueryPerformanceCounter    1 1.4 测试     ...

  5. React Native For Android 架构初探

    版权声明:本文由王少鸣原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/171 来源:腾云阁 https://www.qclo ...

  6. X-UniTMX:导入大型Tiled地图文件(*.tmx)到Unity3d中比较好的插件

    因工作原因,需要导入格子数为1200x1200的Tiled地图文件(*.tmx)到Unity3d中显示出来.尝试过一些其它插件,后面发现X-UniTMX是比较好用的. X-UniTMXhttp://f ...

  7. iOS开发中你是否遇到这些经验问题

    前言 小伙伴们在开发中难免会遇到问题, 你是如何解决问题的?不妨也分享给大家!如果此文章其中的任何一条问题对大家有帮助,那么它的存在是有意义的! 反正不管怎样遇到问题就要去解决问题, 在解决问题的同时 ...

  8. Java 集合系列 11 hashmap 和 hashtable 的区别

    java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...

  9. Java 线程综述

    线程重在 线程同步和线程通信的编程 1.线程与进程?  线程是指程序在执行过程中,能够执行程序代码的一个执行单元.线程的状态:运行.就绪.挂起(suspend).结束; 进程是指一段正在执行的程序. ...

  10. 关于JDBC

    脑补一下JDBC基础知识,原文链接:http://docs.oracle.com/javase/tutorial/jdbc/basics/gettingstarted.html If you are ...