上篇文章给大家解释了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. 火车头采集器如何采集QQ群成员中的QQ号

    如何采集QQ群群员QQ号,采集QQ号,批量采集QQ号 众所周知,QQ群群员QQ号无法导出,即使会员也不可以,那我们只能通过三方工具来实现我们的要求,那今天我们讲讲如何通过火车采集器来采集QQ群群员QQ ...

  2. java中获取两个时间中的每一天

    引入下面方法即可: /** * 获取两个时间中的每一天 * @param bigtimeStr 开始时间 yyyy-MM-dd * @param endTimeStr 结束时间 yyyy-MM-dd ...

  3. AssetManager

    AssetManager用于获取assets下的资源. 1.getassets()得到AssetManager 2.AssetManager.close() 关闭AssetManager 3.Reso ...

  4. 手机配置代理报错invalid host header

    手机配置代理后浏手机弹出页面报错invalid host header,因为我是用fiddler配置的,所以这时候就要看下自己配置完之后,是否重启,重启之后就没问题了. fiddle配置参考:http ...

  5. Dubbo 分布式 日志 追踪

    使用dubbo分布式框架进行微服务的开发,一个大系统往往会被拆分成很多不同的子系统,并且子系统还会部署多台机器,当其中一个系统出问题了,查看日志十分麻烦. 所以需要一个固定的流程ID和机器ip地址等来 ...

  6. java基础---->java8中的函数式接口

    这里面简单的讲一下java8中的函数式接口,Function.Consumer.Predicate和Supplier. 函数式接口例子 一.Function:接受参数,有返回参数 package co ...

  7. Linux服务器性能分析与调优

    一 linux服务器性能查看 1.1 cpu性能查看 1.查看物理cpu个数: cat /proc/cpuinfo |grep "physical id"|sort|uniq|wc ...

  8. linux操作2

    第2天 linux操作系统的目录结构 bin   #可执行程序的安装目录,命令boot #系统启动引导目录dev #设备目录,deviceetc #软件配置文件目录home #用户的家目录lib #系 ...

  9. 24、设计模式、webpack

    利用静态属性:长驻内存 (一) 单例模式 概念:单个实例,只有一个对象,多次创建,返回同一个对象. 单例模式的核心:==确保只有一个实例==,并提供全局访问. //利用了静态属性:长驻内存 funct ...

  10. lucene学习教程

    1Lucene的介绍 ①Lucene是什么: 是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎 ②Lu ...