dump文件解析之探索.Net的内存
前言:对于需要长时间运行的.net程序,有时需要我们查看内存的使用有没有内存泄露问题。 我们可以从dump文件中找到答案。 Dump的看点用dump文件来分析内存,到底我们需要关心哪些点呢?
1.1 ?查看有没有存在有占用大量内存的对象 <比如有某类下面的一个集合> ?1.2? 0 1 2各代的size<查看各代的内存是否有异常> ?????? 2.调查是否有内存泄露(重点) 2.1 ?查看object的根(Root) 看看GC回收不了的有哪些 2.2<我们知道一个对象Root下没有引用就会标为可Gc对象,如果一个对象你希望被gc回收但写代码不注意又在别的地方保存了引用就会出现内存泄露> 3. ?终结器是否被阻塞时,当终结器线程被阻塞时,Finalize会等待累积(末尾有例子) 用什么工具以上三款是微软给我们提供的工具,注意VS得要是Enterprise才可以哦。其他的两款都是免费的。 我们先写一个sample程序 然后运行 ? ? 一.用Visual Studio打开dump文件 ? 点击按钮 【调试托管内存】 ? 可以很清楚的看到有多少对象,每个对象共使用了多少内存 在这个一览下方有2个视图 分别是 1.根的路径? 比如我们选择 ConsoleApp2.B 这个对象 ? 从这个图可以看出来 B 这个对应 的 Paths To Root的追溯情况 (也就是构建最终要GC的Root) ?Program._values(static变量) -> List -> B 我们可以看到values就是B的Root 只要values不存在那B就会纳入gc的回收对象中 因为我们是在Hold住了这个程序的main方法所以在这个时候B 对象还不能被gc回收 2.引用的类型? 如何我们选择List 那么就会展示List ? 从这个图我们可以看出来 List 持有 A[] ,A[]持有 A,A持有B 以上根据这2个视图我们可以利用Vs来看出: ?咦?这个对象占用内存怎么这么大 有点可疑 这个对象不是应该被gc吗,怎么没有被gc呢?研究下他的gc root看看 二.DebugDiag下载地址 ? 点击 【Add Data Files】 添加Dump文件后 点击 【Start Analysis】 执行 执行成功后会自动用 IE 打开。 ? 其实和 VS比起来差不多,直接生成一个报告也是比较方便的! 三.WinDbg虽然使用上比较麻烦但是winDbg可以帮助我们分析的更加详细 可以从微软官方下载,为了方便百度云下载地址: 链接: https://pan.baidu.com/s/1eblPm4nuN0F-DkY_FzqUvA 提取码: zmtd
? 重新设置符号文件路径如下; SRV*C:Symbols*http://msdl.microsoft.com/download/symbols ? 意思是如果在本地找不到则从微软网站下载 Ok设置完成后用WinDbg载入dump文件 ? 如下图所示: ? 打开成功后我们还不能开始分析必须 要先执行加载SOS和CLR(对于.Net?Runtime?4.0) ?【 !loadby sos clr】 命令 接下来我们用WinDbg来调查内存使用情况: 一般我们定位内存泄露问题,我总结的原则是要查到什么对象占用了大量内存,为什么它没有被GC。我们分以下几个步骤 1.统计内存中的对象&查找有异样的对象 使用命令 【!DumpHeap -stat】 可以把堆中的对象类型和size给打印出来 ? 我们可以看出来 A 和 B 是可疑对象 2.根据类型查找存活对象一览接下来我们根据查找出A的一览 使用命令【!DumpHeap -live -mt ? 结果如下: ? 可以看出内存中A类型的对象有100000个 3.探索从某个对象找出GC ROOT一览使用命令【!GCRoot 】 ? 其实可以看出来和Visual Studio的【根的路径】要点差不多吧。 WinDbg的其他常用命令1. !DumpHeap -stat 查找托管堆按类型分组统计个数以及占用的总内存大小2.!HeapStat 查找当前堆中各代的内存使用量 以及剩余使用量3.!DumpHeap -live -mt
|