上篇文章给大家解释了Windbg的基本命令和说明,这一篇给大家介绍内存泄露场景的问题分析。

文章大纲:

  1. 描述问题背景和现象
  2. 确定问题是否是内存泄露
  3. 梳理问题分析思路
  4. 动手分析解决
  5. 总结

1. 先说问题背景:生产环境IIS站点,运行一段时间后,w3wp进程内存会涨到2G,同时内存不释放。

2. 问题确认

打开性能计数器,我们重点看一段时间内,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 个字节和更多字节的对象。

托管堆的内存大小增加的趋势和大对象堆增加的趋势重叠,可以初步推断,内存的增加和大对象有关系!

3. 梳理问题分析思路

连续、间隔抓两个或者三个Dump,每次抓Dump间隔半个小时,或者一个小时,主要看内存的增量。


对比的看每个Dump中:

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

4. 动手分析

  • 多核CPU情况下,分析每个GC托管堆的大小 !eeheap –gc

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

  • 查询内存中大对象的个数和对象大小 !dumpheap –stat -mt -min 5000 -max 100000

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

大对象字符串分析,Session会话数据!同时Session会话中包含了权限数据!

  • 多次采样查看步骤4中对象的gcroot !gcroot addr

  • 打断gcroot中任何一个链条,释放对象引用

5. 总结

总结一下,内存泄露问题分析,有固定的方法和指令,过程需要大家深入理解,同时熟悉代码非常重要,因为需要找出gcroot,分析出内存泄露的原因,再进行修改解决。

大的套路:

  • 描述问题背景和现象
  • 确定问题是否是内存泄露
  • 梳理问题分析思路
  • 动手分析解决
  • 总结

详细的分析步骤:

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

欢迎大家补充。

周国庆

2018/10/30

Windbg程序调试系列2-内存泄露问题的更多相关文章

  1. Windbg程序调试系列3-线程阻塞问题

    上一篇博文给大家分享了使用Windbg分析内存泄露问题: Windbg程序调试系列2-内存泄露问题 本篇我们继续跟大家分享,如何分析解决线程阻塞问题. 从根本上讲,线程阻塞属于程序Hang的一种,其表 ...

  2. Windbg程序调试系列-索引篇

    最近整理了一下Windbg程序调试系列的文章,做个了索引贴,方便大家查询.搜索: Windbg程序调试系列1-常用命令说明&示例 Windbg程序调试系列1-Mex扩展使用总结 Windbg程 ...

  3. Windbg程序调试系列4-Live Debugging

    上篇博文中给大家分享了使用Windbg分析线程阻塞问题: Windbg程序调试系列3-线程阻塞问题 本篇中我们继续,跟大家分享附加进程实时调试-Live Debugging. 先说一下使用Windbg ...

  4. Windbg程序调试系列5-高CPU问题分析

    上篇博客中给大家分享了使用Windbg进行Live Debugging: Windbg程序调试系列4-Live Debugging 本篇中我们继续,跟大家分享常见的应用程序高CPU使用率问题分析. 先 ...

  5. Windbg程序调试系列1-常用命令说明&示例

    Windbg程序调试是.Net高级开发需要掌握的必备技能,分析内存泄露.分析高CPU.分析线程阻塞.分析内存对象.分析线程堆栈.Live Dedugging.这个领域可以说一个技能+场景化应用的结合, ...

  6. Windbg程序调试系列1-Mex扩展使用总结

    最近一直在频繁使用Windbg做线上Dump调试,与微软做Case交流的时候,发现微软CSS团队,用了一个非常效率的Windbg 插件,Mex: 使用介绍: https://blogs.msdn.mi ...

  7. Windows程序调试系列: 使用VC++生成调试信息 转

    Windows程序调试系列: 使用VC++生成调试信息 ZhangTao,zhangtao.it@gmail.com, 译自 “Generating debug information with Vi ...

  8. Windbg调优Kafka.Client内存泄露

    从来没写过Blog,想想也是,工作十多年了,搞过N多的架构.技术,不与大家分享实在是可惜了.另外,从传统地ERP行业转到互联网,也遇到了很所前所未有的问题,原来知道有一些坑,但是不知道坑太多太深.借着 ...

  9. Windbg程序调试--转载

    WinDbg是微软发布的一款相当优秀的源码级(source-level)调试工具,可以用于Kernel模式调试和用户模式调试,还可以调试Dump文件. WinDbg是微软很重要的诊断调试工具: 可以查 ...

随机推荐

  1. php -- 类对象调用静态方法

    以前一直以为 静态方法的调用:类名::静态方法 非静态方法的调用:类对象->非静态方法 最近研究一个类,发现一个比较奇怪的问题,用“类对象->静态方法”这种方式居然成功的调用了静态方法.很 ...

  2. Linux 文件特殊权限_013

    ***Linux 系统文件除了9位基本权限,还有额外3位特殊权限,分别是SUID(setuid),SGID(setgid),SBIT(sticky bit) 一.Linux 系统文件3位特殊权限位说明 ...

  3. R包的小技巧

    通常我们都是直接使用library(pkg_name)  的形式加载R包,在同一台机器上面,对于我们而言,这个包所在的路径一定是在.libPaths() 路面的,但是对于其他用户而言,这个路径可能不存 ...

  4. 蜕变成蝶~Linux设备驱动之watchdog设备驱动

    看门狗(watchdog )分硬件看门狗和软件看门狗.硬件看门狗是利用一个定时器 电路,其定时输出连接到电路的复位端,程序在一定时间范围内对定时器清零 (俗称 “喂狗”),如果程序出现故障,不在定时周 ...

  5. store.state

    https://blog.csdn.net/qq_38658567/article/details/82847758

  6. Nginx子域名配置

    extends:http://blog.csdn.net/xiaoping0915/article/details/53899465 ,http://www.myhack58.com/Article/ ...

  7. Python学习之旅(二十二)

    Python基础知识(21):IO编程 一.文件读写 读写文件就是请求操作系统打开一个文件对象(文件描述符),然后,通过操作系统提供的接口从这个文件对象中读取数据(读文件),或者把数据写入这个文件对象 ...

  8. 【转载】python抓取网页时候,判断网页编码格式

    在web开发的时候我们经常会遇到网页抓取和分析,各种语言都可以完成这个功能.我喜欢用python实现,因为python提供了很多成熟的模块,可以很方便的实现网页抓取.但是在抓取过程中会遇到编码的问题, ...

  9. python全栈开发 * 进程池,线程理论 ,threading模块 * 180727

    一.进程池 (同步 异步 返回值) 缺点: 开启进程慢 几个CPU就能同时运行几个程序 进程的个数不是无线开启的 应用: 100个任务 进程池 如果必须用多个进程 且是高计算型 没有IO型的程序 希望 ...

  10. 找不到 main 方法, 请将 main 方法定义为: public static void main(String[] args) 否则 JavaFX 应用程序类必须扩展javafx.应用程序类必 须扩展javafx.application.Application”

    用eclipse写代码的时候,写了一个简单的程序,编译的时候突然出现“错误: 在类 com.test.demo 中找不到 main 方法, 请将 main 方法定义为: public static v ...