dump文件解析之探索.Net的内存

前言:

对于需要长时间运行的.net程序,有时需要我们查看内存的使用有没有内存泄露问题。

我们可以从dump文件中找到答案。

 

Dump的看点

用dump文件来分析内存,到底我们需要关心哪些点呢?

  1. 内存的使用情况 HeapSize/object的数量 也就是托管堆使用大小以及托管堆内有多少数量的对象

    1.1  查看有没有存在有占用大量内存的对象 <比如有某类下面的一个集合>

      1.2  0 1 2各代的size<查看各代的内存是否有异常>

 

       2.调查是否有内存泄露(重点)

    2.1  查看object的根(Root) 看看GC回收不了的有哪些

    2.2<我们知道一个对象Root下没有引用就会标为可Gc对象,如果一个对象你希望被gc回收但写代码不注意又在别的地方保存了引用就会出现内存泄露>

  3.  终结器是否被阻塞时,当终结器线程被阻塞时,Finalize会等待累积(末尾有例子)

 

用什么工具

  • Visual Studio

  • DebugDiag

  • WinDbg

  • dotMemory(JetBrains旗下的 我还没研究过)

以上三款是微软给我们提供的工具,注意VS得要是Enterprise才可以哦。其他的两款都是免费的。

 

我们先写一个sample程序

640?wx_fmt=png

 

然后运行

 640?wx_fmt=png

 

 640?wx_fmt=png

 

一.用Visual Studio

打开dump文件

 640?wx_fmt=png

 

点击按钮 【调试托管内存】

 640?wx_fmt=png

 

可以很清楚的看到有多少对象,每个对象共使用了多少内存

在这个一览下方有2个视图 分别是

1.根的路径

 640?wx_fmt=png

 

比如我们选择 ConsoleApp2.B 这个对象

 640?wx_fmt=png

从这个图可以看出来 B 这个对应 的 Paths To Root的追溯情况 (也就是构建最终要GC的Root)

 Program._values(static变量) -> List<A> -> B

我们可以看到values就是B的Root 只要values不存在那B就会纳入gc的回收对象中

因为我们是在Hold住了这个程序的main方法所以在这个时候B 对象还不能被gc回收

2.引用的类型

 640?wx_fmt=png

 

如何我们选择List<ConsoleApp3.A>

那么就会展示List<ConsoleApp3.A>的引用关系如下图所示:

 640?wx_fmt=png

 

从这个图我们可以看出来 List<A> 持有 A[] ,A[]持有 A,A持有B

以上根据这2个视图我们可以利用Vs来看出:

 咦?这个对象占用内存怎么这么大 有点可疑

这个对象不是应该被gc吗,怎么没有被gc呢?研究下他的gc root看看

 

二.DebugDiag

下载地址 https://www.microsoft.com/en-us/download/details.aspx?id=49924

 

 640?wx_fmt=png

 

点击 【Add Data Files】 添加Dump文件后 点击 【Start Analysis】 执行

执行成功后会自动用 IE 打开。

 640?wx_fmt=png

 

其实和 VS比起来差不多,直接生成一个报告也是比较方便的!

 

三.WinDbg

虽然使用上比较麻烦但是winDbg可以帮助我们分析的更加详细

可以从微软官方下载,为了方便百度云下载地址:

链接: https://pan.baidu.com/s/1eblPm4nuN0F-DkY_FzqUvA 提取码: zmtd

注意要设置下Symbol Path

 640?wx_fmt=png

 

重新设置符号文件路径如下;

SRV*C:\Symbols*http://msdl.microsoft.com/download/symbols

 640?wx_fmt=png

 

意思是如果在本地找不到则从微软网站下载

 

Ok设置完成后用WinDbg载入dump文件

 640?wx_fmt=png

 

如下图所示:

 640?wx_fmt=png

 

打开成功后我们还不能开始分析必须

要先执行加载SOS和CLR(对于.Net Runtime 4.0)

 【 !loadby sos clr】 命令

 

接下来我们用WinDbg来调查内存使用情况:

一般我们定位内存泄露问题,我总结的原则是要查到什么对象占用了大量内存,为什么它没有被GC。我们分以下几个步骤

1.统计内存中的对象&查找有异样的对象

使用命令 【!DumpHeap -stat】

可以把堆中的对象类型和size给打印出来

 640?wx_fmt=png

我们可以看出来 A 和 B 是可疑对象

2.根据类型查找存活对象一览

接下来我们根据查找出A的一览

使用命令【!DumpHeap -live -mt <MT addr>】

 640?wx_fmt=png

结果如下:

 640?wx_fmt=png

可以看出内存中A类型的对象有100000个

3.探索从某个对象找出GC ROOT一览

使用命令【!GCRoot 】

 

 640?wx_fmt=png

640?wx_fmt=png

 

其实可以看出来和Visual Studio的【根的路径】要点差不多吧。

 

WinDbg的其他常用命令

1. !DumpHeap -stat 查找托管堆按类型分组统计个数以及占用的总内存大小

640?wx_fmt=png

 

2.!HeapStat 查找当前堆中各代的内存使用量 以及剩余使用量

640?wx_fmt=png

 

3.!DumpHeap -live -mt <MT addr> 从MethodTable中查找存活的对象一览

640?wx_fmt=png

 

4.!DumpHeap -dead -mt <MT addr> 从MethodTable中查找要在下次FullGC要回收的一览

640?wx_fmt=png

 

5.!DumpMT -md <MT addr> 查看类型信息 (加了-md参数会把这个类型下的方法(MethodDescriptor)都打印出来)

640?wx_fmt=png

 

6.!DumpClass <EEClass addr> 指定EEClass的地址

640?wx_fmt=png

 

7.!Threads 查看Finalizer有没有导致死锁的例子

640?wx_fmt=png

 

   如上图所示, 用!Threads可以找出 Finalizer的线程为13.。接下来用命令 ~13k 查看线程执行栈,

640?wx_fmt=png

 

 

上图是正常的情况没有问题。执行WaitForFinalizerEvent等下一次执行信号

参考 https://github.com/dotnet/coreclr/blob/ca013149100a9ccc69a5df5b80f29fed2b1b0ce8/src/vm/finalizerthread.cpp#L571

 

 下图是死锁情况

 640?wx_fmt=png

 

可以看到有 CallFinalizer 和 FinalizeAllObjects 表示正在处理什么东西

在用命令【~[ID]e!clrstack】查看CLR的执行栈情况

 640?wx_fmt=png

 

可以看出是在Finalize里面用了 Thread.Sleep导致的

 

 

使用SOSEX更方便的使用WinDbg

sosez是sos的扩展工具集(就是一个dll文件),下载官网地址:http://www.stevestechspot.com/

下载完后要加载到 WinDbg里面去 使用命令 .load 进行加载

 640?wx_fmt=png

它集成了很多简单使用的指令

例如: !mdt 可以根据 类型 进行筛选

 640?wx_fmt=png

 

蓝色处可以直接点击查看,功能很强大

 

 640?wx_fmt=png

 

总结

.Net程序运行期间会遇到很多奇怪的问题,通过分许Dump文件分析内存情况是一个很好的切入口。

不管用什么工具,按照以下几个步骤:

  • 统计内存中的对象

  • 查找有异样的对象 比如这个对象数量多的有点反常,本来期待会被GC回收但是却没有

  •  根据类型查找存活对象一览

  • 探索从某个对象找出GC ROOT一览

一定会让你有所发现。

相关文章:

  • dump解析入门-用VS解析dump文件进行排障

  • 生产环境诊断利器WinDbg帮你快速分析异常情况Dump文件

  • Windbg Extension NetExt 使用指南 ---- NetExt 介绍

  • Windbg Extension NetExt 使用指南  ---- NetExt 的基本命令介绍

  • Windbg Extension NetExt 使用指南  ---- 挖掘你想要的数据 Managed Heap

原文地址: https://www.cnblogs.com/yudongdong/p/9701727.html


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com

640?wx_fmt=jpeg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/319747.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Codeforces Round #654 (Div. 2)

A.Magical Sticks 贪心凑长度为nnn的木棒 #define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #include<iostream> #include<algorithm> using namespace std; int n; int main() {IO;int T;cin>>T;while(T--){cin>>n;cout<<(n1)/…

P3307-[SDOI2013]项链【Burnside引理,莫比乌斯反演,特征方程】

正题 题目链接:https://www.luogu.com.cn/problem/P3307 题目大意 nnn个珠子的一个环形项链&#xff0c;每个珠子有三个1∼k1\sim k1∼k的整数。 两个珠子不同当且仅当它们不能通过翻转或者旋转得到两个项链不同当且仅当它们不能通过旋转得到珠子要求上面的数字互质项链要求相…

【树链剖分】Milk Visits G(luogu 5838)

正题 luogu 5838 题目大意 给你一棵树&#xff0c;和若干查询&#xff0c;每次查询一条路径上是否有点的权值为x 解题思路 离线处理&#xff0c;每次将树上权值为x的点附上1的值&#xff0c;然后询问就是求和&#xff0c;查询完后清零 代码 #include<cstdio> #includ…

2020牛客暑期多校训练营(第二场)

2020牛客暑期多校训练营&#xff08;第二场&#xff09; 最烦英语题 文章目录A All with PairsB BoundaryC Cover the TreeD DurationE Exclusive ORF Fake MaxpoolingG Greater and GreaterH Happy TriangleI IntervalJ Just ShuffleK Keyboard FreeA All with Pairs B Bound…

鸿蒙 - arkTs:状态管理

状态 State&#xff1a; 在声明式UI中&#xff0c;以状态驱动视图更新 状态&#xff08;State&#xff09;&#xff1a;指驱动视图更新的数据&#xff08;被装饰器标记的变量&#xff09;视图&#xff08;View&#xff09;&#xff1a;基于UI描述渲染得到的用户界面 使用示例…

微软发布Azure Pipelines,开源项目可无限制使用CI/CD

微软发布了Azure Pipelines&#xff0c;他们新的CI/CD服务&#xff0c;是Azure DevOps产品的一部分。Azure Pipelines可用于构建、测试和部署工作负载&#xff0c;并可以让各种语言、项目类型和平台协同工作。作为Visual Studio Team Services&#xff08;VSTS&#xff09;的后…

Codeforces Round #653 (Div. 3)

A.Required Remainder 二分 #include<iostream> #include<algorithm> using namespace std; int main() {int T;ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cin>>T;int x,y,n;while(T--){cin>>x>>y>>n;int l0,r(n-y)/x;while(…

【树链剖分】【倍增】宝石(2021GDOI Day2 T1)

正题 luogu 7518 题目大意 给你一棵树&#xff0c;一条路径的价值为&#xff1a;路径上点权以1开始依次递增1的子序列&#xff0c;有q次询问&#xff0c;每次询问一条路径的价值 解题思路 n,m值比较大&#xff0c;对于每次询问只有O(log2n)O(log^2n)O(log2n)的时间 考虑树链…

2020牛客暑期多校训练营(第一场)

文章目录A B-Suffix ArrayB Infinite TreeC DominoD Quadratic FormE Counting Spanning TreesF Infinite String Comparision题意&#xff1a;题解&#xff1a;代码&#xff1a;G BaXianGuoHai, GeXianShenTongH Minimum-cost FlowI 1 or 2J Easy Integration题意题解代码2020…

P4755-Beautiful Pair【笛卡尔树,线段树】

正题 题目链接:https://www.luogu.com.cn/problem/P4755 题目大意 nnn个数字的一个序列&#xff0c;求有多少个点对i,ji,ji,j满足aiaj≤max{ak}(k∈[l,r])a_i\times a_j\leq max\{a_k\}(k\in[l,r])ai​aj​≤max{ak​}(k∈[l,r]) 解题思路 如果构建一棵笛卡尔树的话那么两个点…

C# 接受MQTT服务器推送的消息

前言&#xff1a;MQTT是IBM开发的一个即时通讯协议。MQTT是面向M2M和物联网的连接协议&#xff0c;采用轻量级发布和订阅消息传输机制。大家可以直接上GitHub下载MQQT服务的源码&#xff0c;源码地址&#xff1a;https://github.com/mqtt/mqtt.github.io/wiki/libraries主要内容…

【堆】【DP】Niyaz and Small Degrees(luogu 7600[APIO 2021 T3]/luogu-CF1119F)

正题 luogu 7600[APIO 2021 T3] luogu-CF1119F 题目大意 给你一棵树&#xff0c;给出每条边割掉的代价&#xff0c;问你对于0⩽k<n0\leqslant k<n0⩽k<n&#xff0c;使得每个点的度数小于k的最小代价 解题思路 首先考虑单询问的情况 可以设fx,1/0f_{x,1/0}fx,1/0​…

Boundary(2020多校第二场B)

Boundary&#xff08;2020多校第二场B&#xff09; 文章目录题意&#xff1a;题解&#xff1a;思路1&#xff1a;代码&#xff1a;思路二代码题意&#xff1a; 坐标平面有n个点&#xff08;不与原点&#xff08;0,0&#xff09;重复&#xff09;,现考虑一个圆&#xff0c;&…

.NET Core开发日志——Linux版本的SQL Server

SQL Server 2017版本已经可以在Linux系统上安装&#xff0c;但我在尝试.NET Core跨平台开发的时候使用的是Mac系统&#xff0c;所以这里记录了在Mac上安装SQL Server的过程。最新的SQL Server没有专门为Mac系统准备安装包&#xff0c;但由于Mac系统上支持Docker&#xff0c;所以…

P3313-[SDOI2014]旅行【树链剖分,线段树】

正题 题目链接:https://www.luogu.com.cn/problem/P3313 题目大意 nnn个点的一棵树&#xff0c;每个点有一个颜色和权值&#xff0c;有操作 修改一个点的权值修改一个点的颜色询问一条路径的某颜色的权值和询问一条路径的某颜色的权值最大值 解题思路 询问路径直接树剖先&am…

AIsing Programming Contest 2020 总结

A - Number of Multiples 按照题目意思走就行 #define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #include<iostream> #include<algorithm> using namespace std; int l,r,d; int main() {IO;cin>>l>>r>>d;if(r<l) swap(l,r);…

【倍增】【线段树】雨林跳跃(luogu 7599[APIO 2021 T2])

正题 luogu 7599[APIO 2021 T2] 题目大意 给你一排树中每棵树的高度&#xff0c;每次跳跃可以跳到左/右边第一棵比该树高的树&#xff0c;问你从A-B中某棵树跳到C-D中的某棵树的最小步数&#xff08;A⩽B<C⩽DA\leqslant B< C\leqslant DA⩽B<C⩽D&#xff09; 解题…

Duration(2020多校第二场D)

Duration&#xff08;2020多校第二场D&#xff09; 文章目录题意题解代码首先&#xff0c;非常感谢出题人出这个题&#xff0c;避免了我全wa的尴尬题意 求两个时间相差多少秒&#xff0c;两个时间为同一天 题解 全部转化成秒&#xff0c;然后求差 代码 #include<bits/s…

dotnetClub 的前世今生

三年之前&#xff0c;我做过一个在线调查&#xff0c;当时有不少人还是对一个在线社区表示出期待。.NET Core 技术正风声水起&#xff0c;所以我就开始了用它来开发一个论坛的计划。最近正式将项目推动到了一个 MVP 的状态。感兴趣的朋友&#xff0c;现在可以访问 preview.dotn…

P3308-[SDOI2014]LIS【最小割】

正题 题目链接:https://www.luogu.com.cn/problem/P3308 题目大意 三个nnn个数字的序列A,B,CA,B,CA,B,C。要求删除其中某些位置iii使得AAA的最长上升子序列至少减少111且删去位置BBB的权值和最小的情况下满足删去位置的CCC值升序排序后字典序最小。 解题思路 首先BBB值最小很…