首页 > 系统相关 >WinDbg排查.net性能或内存问题步骤简述

WinDbg排查.net性能或内存问题步骤简述

时间:2023-08-27 12:11:50浏览次数:45  
标签:.__ WinDbg 查看 Canon System mscorlib 简述 线程 net

目录


一、安装WinDbg

第一步当然是安装了,需要注意的是,千万不要搜索 windbg 然后下载,搜索到的windbg安装文件,都不是我们想要的,真正的windbg,实际上是在微软的SDK里,下载链接在这里:
https://developer.microsoft.com/en-US/windows/downloads/windows-10-sdk
点击这个网页里的 DOWNLOAD THE .ISO,文件大概814M ,等下载完成后,解压,运行安装程序,
在安装组件选择处,选择 Debugging Tools for Windows 即可,其它项可以不安装;
按步骤安装完成后,你的桌面上或开始菜单里,就有WinDbg(X64)的快捷方式了,双击它就跑起来了。

二、诊断数据获取

在目标机器上,打开任务管理器,进入“详细信息”标签页,找到有问题的进程,按右键,选择“创建转储文件”,等个1,2分钟,就会出现创建成功,并显示文件所在位置,这个文件就是我们要诊断的dmp数据了:
注意:创建转储文件会暂停进程,如果是线上服务,要评估影响。

在这里插入图片描述

三、加载分析

  1. 打开WinDbg(X64),点击菜单的“File”=》Open Crash Dump…
    找到上个步骤生成的dmp文件,点击打开,并等待加载完成(即命令行没有显示BUSY字样):
    在这里插入图片描述

  2. 打开文件后,进行环境初始化,先创建目录 D:\Symbol,然后在WinDbg里执行如下命令:
    2.1、从微软下载Symbol档,并缓存到D盘的Symbol下:
    .sympath srv*D:\Symbol*https://msdl.microsoft.com/download/symbols
    2.2、指定显示完整的Symbol下载信息:
    !sym noisy
    3、自动加载CLR诊断相关模块,如果要分析其它机器的dump文件时,比较好用:
    .cordll -ve -u -l
    需要注意的是:有时加载其它机器的文件还是会无法加载,可以在dmp文件所在的机器上安装windbg进行诊断。

  3. OK,可以开始用WinDbg的命令进行排查和诊断了
    3.1、常用命令:
    查看引起CPU过高命令比如:

!threadpool 查看线程池CPU占用,包括总线程数、队列请求数、CP线程数。
!threads -special 查看每个线程状态
!runaway 查看每个线程的CPU占用时间,可以找到哪个线程占用时间更高。
~number s 切换到指定线程,number为具体线程的ID。
kb 查看当前线程堆栈
!clrstack 切换到具体的线程后,用此命令查看当前线程的托管代码。类似于 !dumpstack -EE
!clrstack -a 表示显示所有参数信息和变量信息
!eestack -EE 相当于在所有线程上执行 dumpstack (参数EE表示只显示托管代码)
!name2ee 查看指定文件的指定类的MethodTable,EEClass等信息,如
!name2ee * RabbitMQ.Client.Impl.Frame
根据提示,用 !dumpmt 地址 查看具体的MethodTable信息;
!dumpmt 找到相关MethodTable处的相关信息。
!dumpmd 根据MethodDesc找到相关模块信息,比如MethodTable.
!dumpdomain 显示所有域里的程序集,或者根据参数获取指定域。
!savemodule 根据具体程序集地址,把当前程序集的代码生成到指定文件

查看占用内存过高的命令比如:

!eeheap 查看堆中信息,可以查看到大对象。
!dumpheap 查看GC堆中信息,一般带-min,-stat,-type等参数。
!dumpheap -stat 按对象类型排序输出所有对象个数、占用字节数
注:Free这项: 0118c800 101 14824 Free
这项一般都是GC还未压缩空间或一些堆上分配的禁止GC回收的pinned object(非托管对象或unsafe指针对象).
!dumpheap -type System.String -min 100 查找堆上大于100字节的字符串,注:-min 85000(大于85000字节的字符串或对象将存储在大对象堆上)
!dumphead -mt xxxxx 类型不确定时,用mt串查找
!do 地址 查看指定地址存放的数据信息
!gcroot 地址 根据堆地址,查看相关模块引用代码信息,如果没找到,表示等待回收。
!gcgen 地址 根据堆地址,看它的代龄,0代,1代,2代,试了好像没有这个指令

!help 命令 可以查看指定命令的帮助信息
注意:调试Dump一定要用对应版本的WinDbg,比如32位系统Dump要用WinDbg-x32

以下步骤是分析死锁的命令:

1、 !threadpool 查看Worker Thread工作线程数
2、!threads 查看后台线程数
3、 !locks 查看死锁,如果没有数据,要改用
!SyncBlk
Index SyncBlock MonitorHeld Recursion Owning Thread Info SyncBlock Owner
295 0000009ad30235c8 3 1 0000009ad2deec60 4eac 37 00000097c014be58 ASP.global_asax
341 0000009acc5abaa8 3 1 0000009acc259d80 1494 27 000000984025f0c8 ASP.global_asax
上表意思:4eac线程(37号线程)占用了资源 00000097c014be58,阻塞了 (3 - 1)/ 2 = 1个线程(3表示 MonitorHeld)

4、~* kv 查找所有线程数据,在里面搜索 c014be58
可以看到 35线程和37线程都要用这个资源

5、~35s 切换线程,再用 !clrstack -a 查看堆栈

6、 用 !dso 查看线程堆栈上的对象

四、举例分析

以下步骤是分析高CPU占用的命令

1、用命令找出占用CPU时间最多的线程: !runaway 结果参考(都是CPU占用10分钟以上的线程):
0:035> !runaway
User Mode Time
Thread Time
39:14b4 0 days 0:10:53.187
35:948 0 days 0:10:53.156
38:938 0 days 0:10:52.984
40:14e4 0 days 0:10:51.578
36:16f8 0 days 0:09:53.265

2、用命令切换到指定线程,如切换到线程27:~27s 结果参考:(注:该步骤会下载 mscorlib.ni.pdb)
0:035> ~39s
mscorlib_ni+0x4d9586:
00007ffac3e99586 488b4610 mov rax,qword ptr [rsi+10h] ds:000000f595cf9510=000000f495c35318

3、用命令显示指定线程的堆栈信息:!clrstack 结果参考:(注:该步骤会下载 clr.pdb)
0:039> !clrstack
OS Thread Id: 0x14b4 (39)
Child SP IP Call Site
000000f7a3ecbfb0 00007ffac3e99586 System.Collections.Generic.Dictionary2[[System.__Canon, mscorlib],[System.__Canon, mscorlib]].FindEntry(System.__Canon) 000000f7a3ecc020 00007ffac3e70ae4 System.Collections.Generic.Dictionary2[[System.__Canon, mscorlib],[System.__Canon, mscorlib]].TryGetValue(System.__Canon, System.__Canon ByRef)
000000f7a3ecc060 00007ffa6655befd Mike.Domain.DapperProvider.DapperUtil.GetPrimaryKeyName(System.Type)
000000f7a3ecc0c0 00007ffa6655b48e Mike.Domain.DapperProvider.DapperRepository`2[[System.__Canon, mscorlib],[System.Int64, mscorlib]]…ctor()
000000f7a3ecc110 00007ffa664c22f8 DynamicClass.lambda_method(System.Runtime.CompilerServices.Closure)
000000f7a3ecc140 00007ffa6655ae78 Mike.Tool.Core.Constructor.CreateInstance()
000000f7a3ecc190 00007ffa6655acb2 Mike.Tool.Core.ClassLoader.GetInstance[System.__Canon, mscorlib]
000000f7a3ecc1e0 00007ffa6655aade Mike.Tool.Core.ClassLoader.GetSingleInstance[System.__Canon, mscorlib]

第3步的结果里,可以看到卡在Dictionary.FindEntry方法上,
再切换到其它几个线程,都可以看到,卡在同一个方法上,基本上可以判定是Dictionary的线程不安全导致的问题,
解决方法,要么替换成ConcurrentDictionary,要么对关键的读取 和 修改代码进行lock了

==========================================================================================
以下步骤是分析高内存占用的命令:
1、用命令找出占用内存最多的对象: !dumpheap -stat 结果参考:
0:039> !dumpheap -stat
Statistics:
MT Count TotalSize Class Name
00007ffac4c31ea0 1 24 System.Collections.Generic.GenericEqualityComparer1[[System.Int64, mscorlib]] 00007ffac4c03738 1 24 System.Collections.Generic.GenericEqualityComparer1[[System.UInt64, mscorlib]]
00007ffac40791a8 984 118080 System.Reflection.RuntimeParameterInfo
00007ffac405c1b8 676 180528 System.Collections.Hashtable+bucket[]
00007ffac4057c20 853 197198 System.Char[]
000000f31516c8b0 2659 197852 Free
00007ffac40570b0 9886 237264 System.Object
00007ffac4073548 2207 247184 System.Reflection.RuntimeMethodInfo
00007ffac4059498 2345 249196 System.Int32[]
00007ffac40dae60 7 356424 System.Int64[]
00007ffac4057148 2099 435992 System.Object[]
00007ffac4092388 21860 874400 System.Threading.QueueUserWorkItemCallback
00007ffac4056ad0 11232 1103744 System.String
00007ffac4092090 1316 1805664 System.Threading.IThreadPoolWorkItem[]
00007ffac405be10 1401 3657601 System.Byte[]
Total 104448 objects
2、查看具体的类的内存:
!dumpheap -type System.Web.Caching.CacheEntry 命令,查看所有具体的CacheEntry地址等信息,
注意:这个数据太大,要加一个范围比较好,例如:
!dumpheap -type Mike.Promotion.Service.Dto.VoucherDishDto 0 0x0000001700202000
这后面2个参数,0表示起始,0x0000001700002000表示结束,结束值从 !eeheap -gc 的输出结果里:generation 2 starts at的值,增加一点范围就好

3、 !eeheap -gc 查看托管堆

本文摘自

版权声明:本文为CSDN博主「游北亮」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/youbl/article/details/88893182

标签:.__,WinDbg,查看,Canon,System,mscorlib,简述,线程,net
From: https://www.cnblogs.com/lanwah/p/17660113.html

相关文章

  • WinDbg基本环境搭建及安装
    目录安装配置与调试符号文件配置加载SOS.dll特殊情况的处理1.32位兼容程序的调试2.clr运行环境不符的调试3.调试其他机器上的内存转储文件4.其他常见问题Q&A其他参考链接文章摘自安装有2个方式可以安装WinDbg。新版安装WinDbgPreview在商店里搜WinDbg直接就可以安装,这......
  • ASP.NET-MVC项目搭建
    目录零、资料一、零、资料ASP.NETMVC:https://www.bilibili.com/video/BV1q64y1z7zS/一、......
  • 开源.NetCore通用工具库Xmtool使用连载 - XML操作篇
    【Github源码】《上一篇》介绍了Xmtool工具库中的发送短信类库,今天我们继续为大家介绍其中的XML操作类库。XML操作是软件开发过程中经常会遇到的情况;包括XML内容的遍历解析,或者特定值内容的查询获取等等。Xmtool工具库提供了一种更方便的方式对Xml进行遍历解析或者对特定节点内......
  • ASP.NET-WebForm项目搭建
    目录零、开发环境一、创建工程二、发布项目三、拖拽式-调整页面零、开发环境vs2022chromeIIS服务器一、创建工程1、新建项目:2、选择web应用程序、3、设置项目存放的路径4、选择webForm的模板5、创建一个名为webs的文件夹,用于存放aspx页面:6、创建一个......
  • 科学网—VBox虚拟机中,deepin系统下共享文件夹 - 苏威的博文 (sciencenet.cn)
    科学网—VBox虚拟机中,deepin系统下共享文件夹-苏威的博文(sciencenet.cn) mount-tvboxsfnn(共享文件夹名称)/home/shared......
  • Acunetix v23.7 (Linux, Windows) - 漏洞扫描 (Web 应用程序安全测试)
    Acunetixv23.7(Linux,Windows)-漏洞扫描(Web应用程序安全测试)Acunetix|WebApplicationSecurityScanner请访问原文链接:https://sysin.org/blog/acunetix-23/,查看最新版。原创作品,转载请保留出处。作者主页:sysin.org重要提示AcunetixPremium现在使用日历化版本......
  • window7 无法安装Net48的问题
    此操作系统不支持.NETFramework4.8.1。-『悬赏问答区』-吾爱破解-LCG-LSG|安卓破解|病毒分析|www.52pojie.cn安装一个4.8的离线包,下载地址:https://download.visualstudio.microsoft.com/download/pr/2d6bb6b2-226a-4baa-bdec-798822606ff1/8494001c276a4b96804cde7829......
  • 给微软.Net runtime运行时提交的几个Issues
    前言因为目前从事的CLR+JIT,所以会遇到一些非常底层的问题,比如涉及到微软的公共运行时和即时编译器或者AOT编译器的编译异常等情况,这里分享下自己提的几个Issues。原文:微软.Netruntime运行时提交的几个IssuesIssues一.issuesone第一个System.Numerics.Vector库里面的成员......
  • 关于Kubernetes-v1.23.6-集群测试-创建一个nginx的deployment进行验证
    关于k8s集群环境搭建完成后,我们可以通过创建一个deployment进行效果的测试这里以nginx为例,还是在k8s-master上进行创建kubectlcreatedeploymentnginx--image=nginxkubectlexposedeploymentnginx--port=80--type=NodePort这里--port只是指定了容器(container )暴......
  • 【873】Python读取NetCDF中的scale_factor和add_offset
    参考:python中scale的用法_在netCDF4和Python中使用scale_factor和add_offset的示例?参考代码:importnetCDF4asncdir_path="./2m_temperature/03_TIFF/"files=os.listdir(dir_path)files=sorted(files)forfileinfiles:iffile.find('.tiff')<......