乐趣区

关于.net:使用Windbg快速分析应用内存泄露问题

Windbg 程序调试是.NET 高级开发须要把握的必备技能,剖析内存泄露、剖析 CPU 高使用率、剖析线程阻塞、剖析内存对象、剖析线程堆栈、Live Dedugging。这些 Debug 畛域能够说一个技能 + 场景化利用的联合,如果只依附 Windbg 几个简略的命令,不了解每个指令在理论 Troubleshooting 中的作用,是没有意义的。工欲善其事必先利其器,咱们先从罕用的命令和示例说起。

Windbg 常用命令

先筹备一个 Dump 文件,倡议应用 64 位应用程序。例如:64 位 IIS 利用的 w3wp 过程,64 位 exe 过程都能够。如果抓 Dump 文件,很简略:工作管理器 - 过程 - 右键【创立转储文件】。

而后下载并装置 Windbg,下载链接:https://developer.microsoft.c…,一路下一步,抉择【Debugging Tools for Windows】。



关上之后,Ctrl+D,关上第一步抓的 Dump 文件,开始明天的常用命令介绍。

  1. 加载 SOS 调试扩大 dll。
.loadby sos clr
  1. 设置并从新加载调试符号文件的命令,将.Net 一些重要的 pdb 文件下载到指定的门路中,加载到 Windbg 调试环境中,这样,咱们就能够看到程序在哪一行出错,运行到哪一行了。
.symfix+ C:\symbols
.reload
  1. 打印以后调试符号文件搜寻门路。
0:000> .sympath
  1. 查看线程池,剖析并确认 CPU 使用率,能够应用哪个指令。
0:000> !threadpool
CPU utilization: 2%
Worker Thread: Total: 19 Running: 2 Idle: 17 MaxLimit: 32767 MinLimit: 4
Work Request in Queue: 0
--------------------------------------
Number of Timers: 2
--------------------------------------
Completion Port Thread:Total: 4 Free: 4 MaxFree: 8 CurrentLimit: 4 MaxLimit: 1000 MinLimit: 4
  1. 查看线程的整体运行状况。

!threads

  1. 查问指定线程的调用堆栈,例如 34 号线程。
 ~34s

!clrstack

  1. 查看线程耗费 CPU 资源状况。

!runaway

第一列是线程号,第二列是 Total 的 CPU 应用工夫

  1. 查看以后线程栈上所有对象的信息,Dump stack objects。

  1. 查问内存中指定对象的信息 Dump object。
!do
  1. 查问内存中指定数组对象的信息 Dump Array。

!de

  1. 查看以后线程的堆栈和每行堆栈上的变量信息。
!clrstack -a
  1. Windbg 附加过程调试,启用 CLR 异样捕捉、查看异样、查看异样所在线程堆栈、禁用 CLR 异样调试、退出调试。
sxe clr
g
!pe
!clrstack
sxd clr
qd
  1. 查看托管堆上内存对象的散布、三个代的信息。
!eeheap -gc

  1. 查看托管堆上加载的 Dll。

!eeheap -loader

  1. 查问内存中各类对象的总个数和总内存占用。
!dumpheap  -stat
  1. 查问内存中大对象的个数和对象大小。
!dumpheap -stat  -mt -min 85000
  1. 查看内存的析构队列的指令。

!finalizequeue

  1. 请输出查看对象 000000123557DFC0 的 gcroot 的指令。

!gcroot 000000123557DFC0

  1. 查看线程阻塞的指令。

!syncblk

  1. 查看 Dump 中所有 System.Net.Sockets.Socket 对象统计信息的指令。
!dumpheap -type System.Net.Sockets.Socket -stat

以上是 Windbg 罕用的命令和应用阐明,接下来和大家分享应用 Windbg 剖析.NET 利用内存泄露问题。

应用 Windbg 剖析.NET 利用内存泄露问题

咱们按以下的思路开展明天的分享:

  1. 形容问题背景和景象
  2. 确定问题是否是内存泄露
  3. 整顿问题剖析思路
  4. 入手剖析解决
  5. 总结复盘

先说问题背景

生产环境 IIS 站点,运行一段时间后,w3wp 过程内存会涨到 2G,同时内存不开释。

问题确认

关上性能计数器,咱们重点看一段时间内,IIS 站点 w3wp 过程相干的性能计数器的变动:

性能计数器中:有三个十分重要:

  • .NET CLR Memory/Gen 2 heap size
  • .NET CLR Memory/Gen 1 heap size
  • .NET CLR Memory/Gen 0 heap size

托管堆上的对象有三代:

第 0 代:

这是最年老的代,其中蕴含短生存期对象。短生存期对象的一个示例是长期变量。垃圾回收最常产生在此代中。新调配的对象形成新一代的对象并且为隐式的第 0 代回收,除非它们是大对象,在这种状况下,它们将进入第 2 代回收中的大对象堆。大多数对象通过第 0 代中的垃圾回收进行回收,不会保留到下一代。

第 1 代:

这一代蕴含短生存期对象并用作短生存期对象和长生存期对象之间的缓冲区。

第 2 代:

这一代蕴含长生存期对象。长生存期对象的一个示例是服务器应用程序中的一个蕴含在过程期间处于活动状态的静态数据的对象。
当条件失去满足时,垃圾回收将在特定代上产生。回收某个代意味着回收此代中的对象及其所有更年老的代。第 2 代垃圾回收也称为残缺垃圾回收 FullGC,因为它回收所有代上的所有对象(即,托管堆中的所有对象)。

幸存和晋升:

垃圾回收中未回收的对象也称为幸存者,并会被晋升到下一代。在第 0 代垃圾回收中幸存的对象将被晋升到第 1 代;在第 1 代垃圾回收中幸存的对象将被晋升到第 2 代;而在第 2 代垃圾回收中幸存的对象将仍为第 2 代。
通过代晋升,看对象的存活工夫!

Process/Private Bytes
Process/Virtual Bytes
.NET CLR Memory/# Bytes in all Heaps : CLR 内存托管堆的大小
.NET CLR Memory/Large Object Heap Size: 大对象堆蕴含其大小为 85,000 个字节和更多字节的对象。

托管堆的内存大小减少的趋势和大对象堆减少的趋势重叠,能够初步推断,内存的减少和大对象有关系!

整顿问题剖析思路

间断、距离抓两个或者三个 Dump,每次抓 Dump 距离半个小时,或者一个小时,通过多个 Dump 比照着看内存的增量。

比照的看每个 Dump 中:

  • 多核 CPU 状况下,剖析每个 GC 托管堆的大小 !eeheap –gc
  • 查问内存中各类对象的总个数和总内存占用 !dumpheap –stat
  • 查问内存中大对象的个数和对象大小 !dumpheap –stat -mt -min 85000
  • 如果某一类或者几类对象的内存总占用很多,剖析此类对象 !dumpheap –mt *
  • 屡次采样查看步骤 4 中对象的 gcroot !gcroot addr

打断 gcroot 中任何一个链条,开释对象援用

入手剖析解决

多核 CPU 状况下,剖析每个 GC 托管堆的大小 !eeheap –gc。

查问内存中各类对象的总个数和总内存占用 !dumpheap –stat。

查问内存中大对象的个数和对象大小 !dumpheap –stat -mt -min 85000。

如果某一类或者几类对象的内存总占用很多,剖析此类对象 !dumpheap –mt * -stat。

大对象字符串剖析,能够上图联合具体的代码,能够发现是用户 Session 会话数据!同时 Session 会话中蕴含了整个用户的权限数据!

屡次采样查看步骤 4 中对象的 gcroot !gcroot addr。

打断 gcroot 中任何一个对象的连贯援用,实现对象援用的开释。

总结

剖析解决.NET 应用程序的内存泄露问题,大抵的套路是这样的:

  • 形容问题背景和景象
  • 确定问题是否是内存泄露
  • 梳理问题剖析思路
  • 入手剖析解决
  • 总结复盘

具体的剖析步骤如下:

  • 多核 CPU 状况下,剖析每个 GC 托管堆的大小 !eeheap –gc
  • 查问内存中各类对象的总个数和总内存占用 !dumpheap –stat
  • 查问内存中大对象的个数和对象大小 !dumpheap –stat -mt -min 85000
  • 如果某一类或者几类对象的内存总占用很多,剖析此类对象 !dumpheap –mt *
  • 屡次采样查看步骤 4 中对象的 gcroot !gcroot addr
  • 打断 gcroot 中任何一个援用链条,开释对象援用

.NET 应用程序的内存泄露问题剖析,有固定的办法和套路,整个剖析过程须要大家深刻了解,同时对代码的相熟十分重要,以上分享心愿能对大家的日常线上问题剖析有所帮忙。

微软最有价值专家(MVP)

微软最有价值专家是微软公司授予第三方技术专业人士的一个寰球奖项。28 年来,世界各地的技术社区领导者,因其在线上和线下的技术社区中分享专业知识和教训而取得此奖项。

MVP 是通过严格筛选的专家团队,他们代表着技术最精湛且最具智慧的人,是对社区投入极大的激情并乐于助人的专家。MVP 致力于通过演讲、论坛问答、创立网站、撰写博客、分享视频、开源我的项目、组织会议等形式来帮忙别人,并最大水平地帮忙微软技术社区用户应用 Microsoft 技术。
更多详情请登录官方网站:
https://mvp.microsoft.com/zh-cn


欢送关注微软中国 MSDN 订阅号,获取更多最新公布!

退出移动版