Windbg程序调试系列2-内存泄露问题

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

文章大纲:性能

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

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

2. 问题确认对象

打开性能计数器,咱们重点看一段时间内,IIS站点w3wp进程相关的性能计数器的变化:blog

性能计数器中:有三个很是重要:进程

.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 个字节和更多字节的对象。字符串

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

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

相关文章
相关标签/搜索