VS 使用vs2017自带的诊断工具(Diagnostic Tools)诊断程序的内存问题
前言
一般来说.NET程序员是不用担心内存分配释放问题的,因为有垃圾收集器(GC)会自动帮你处理。但是GC只能收集那些不再使用的内存(根据对象是否被其它活动的对象所引用)来确定。所以如果代码编写不当的话,仍然会出现内存泄漏的问题,常见的情况有:一个静态变量引用了一个应该被释放的对象,事件注册后不解除注册,非托管资源使用后没有手动释放。不断的内存泄漏终会引起内存不足,挂掉你的程序。
对于这种内存泄漏问题,有很多的分析工具可以使用,常见的有CLRProfiler、ANTS Performance Profiler等。不过从vs2013起,vs自带了一个分析工具-Diagnostic Tool,默认debug时会自动打开,如果没有打开的话就按快捷键Ctrl+Alt+F2。
如下图:
开始使用
这里以静态变量持有应释放的对象为例,简单介绍下使用方法。
这里有个winform程序,主要功能即使点击按钮后,输出名为“jim”的个人信息:
private void button1_Click(object sender, EventArgs e)
{
var p = PersonManager.Get("jim");
label1.Text += p.Name + " " + p.Age + "\n";
}
- 1
- 2
- 3
- 4
- 5
Person和PersonManager类的信息如下:
namespace MemLeak
{
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public byte[] BinaryData { get; set; }
}
public static class PersonManager
{
static List<Person> people = new List<Person>();
public static List<Person> People
{
get
{
return people;
}
}
public static Person Get(string name)
{
//正常逻辑
//var per = People.FirstOrDefault(o => o.Name == name);
//if(per==null)
//{
// per = new Person();
// per.Age = 23;
// per.Name = name;
// per.BinaryData = File.ReadAllBytes(@"D:\2.zip");//一个38MB的文件
// people.Add(per);
//}
//return per;
//错误逻辑
Person p = new Person();
p.Age = 23;
p.Name = name;
p.BinaryData = File.ReadAllBytes(@"D:\2.zip");//一个38MB的文件
people.Add(p);
return p;
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
1. 捕获内存快照
程序运行起来后,从下图可以看到内存占用大约在18M左右,此时点击“截取快照”新建一个快照:
然后click按钮5次,然后再点击 截图快照 ,如下:
从曲线图中可以明显看到内存从18M逐步增长到227M。第二次快照与第一次相比对象增加了19个,堆上的内存使用增加了191M左右。
点击图中的(+19)字样,可以进入到快照详细对比界面。
2. 详细对比
如图所示,我们先来看下选中的那一行是什么意思:
可以看到MemLeak.Person这个对象的计数差异为+5,计数是5。表示这两次快照之间这个Person对象从0个变成了5个增加了5个。大小差异是增加了195601040个字节,这几个从字面意思看都很好理解。唯一有点难度的可能是非独占大小(字节),一眼看不出来是干什么的。但是我们注意到了List<MemLeak.Person>对象的大小是68字节而非独占大小却是195601108字节。
非独占大小的统计方式如下:
其中最下层的string和byte[],由于没有子节点了,所以它们的非独占大小就是它们本身的大小。Address的非独占大小=自己本身的大小+String的非独占大小(50字节)+Byte[]的非独占大小(100字节)=200字节。Customer的非独占大小=自己本身(100字节)+String的非独占大小(100字节)+Address的非独占大小(200字节)=400字节。
所以这也就解释了List<MemLeak.Person>,自身大小仅是68字节,但是由于它是一个List内部包含了5个Person对象,所以它的非独占大小就是5个Person对象大小的和。
3. 哪里产生了泄漏?
这里我先将过滤器里“仅我的代码”和“折叠小型对象类型”前面的勾去掉,便于分析。
因为我们值需要看当前程序集(MemLeak)的内存信息,所以在搜索类型名的框里直接输入我们程序集的名称,将其他一些没用的过滤掉。
是不是清爽了很多!
分析内存当然要拿占用内存增多最大的对象开刀,点击MemLeak.Person,在下面的“根的路径”视图中可以看到增加的5个Person对象是在一个Person[]数组中。
但是我们好像并没有声明过这样的数组,所以继续展开:
原来是在一个List里面,而且这个List还是静态的。这时候就要想到内存泄漏的原因,可能就是代码哪里的静态变量持续占有应该释放的对象了。然后更改为正确代码就OK了。
4. 查看对象中哪种数据类型占用内存较多?
切换到的引用选项卡(“引用的类型”)。
可以看到本例中Person的Byte[]类型的占用内存较多,所以我们就可以重点排查Person中哪里用到了Byte[]类型,进而去优化。
当初取消勾选的那两个选项是什么?
第一个是“仅我的代码”:
勾上之后,会过滤掉那些.Net Runtime产生的一些对象和一些很常见的系统认为与你的程序无关的一些对象。
第二个是:“折叠小的对象类型”:
勾上后,会过隐藏掉那些非独占大小小于托管堆总大小0.5%的对象。将这些小对象的非独占大小合并的父节点中。如下:
这两个选项默认都勾上即可。
其它
对于生产环境中的软件,分析内存时可以多次抓取dump文件,用vs打开后分析比对。
不过只有vs的企业版才有这个功能。
https://blog.csdn.net/catshitone/article/details/79002823
VS 使用vs2017自带的诊断工具(Diagnostic Tools)诊断程序的内存问题的更多相关文章
- 【VS】使用vs2017自带的诊断工具(Diagnostic Tools)诊断程序的内存问题
前言 一般来说.NET程序员是不用担心内存分配释放问题的,因为有垃圾收集器(GC)会自动帮你处理.但是GC只能收集那些不再使用的内存(根据对象是否被其它活动的对象所引用)来确定.所以如果代码编写不当的 ...
- 如何禁用/关闭vs2017自带的Git工具的?
对于用习惯了独立Git工具和命令行的人来说,看到Visual Studio自带的Git工具后,很是别扭,到处充满了不习惯,而且是不是还会出现电脑卡顿的现象(可能是我自身电脑配置一般的问题). 如何关闭 ...
- 容器内的Linux诊断工具0x.tools
原创:扣钉日记(微信公众号ID:codelogs),欢迎分享,转载请保留出处. 简介 Linux上有大量的问题诊断工具,如perf.bcc等,但这些诊断工具,虽然功能强大,但却需要很高的权限才可以使用 ...
- Vs2015 c# 诊断工具查看程序的占用情况
windbg用着还不熟悉,dottrace 还要版权,着急查看程序的cpu 的使用情况,因为程序开启之后占用处理器资源较大,问题在哪里呢,于是点开了vs2015自带的诊断工具,以前偶尔打开过,没发现 ...
- 使用vs自带的性能诊断工具
visual studio是个强大的集成开发环境,内置了程序性能诊断工具.下面通过两段代码进行介绍. static void Main( string[] args) { Test1(); Test2 ...
- vs2017诊断工具
vs2017诊断工具
- 中小研发团队架构实践之生产环境诊断工具WinDbg 三分钟学会.NET微服务之Polly 使用.Net Core+IView+Vue集成上传图片功能 Fiddler原理~知多少? ABP框架(asp.net core 2.X+Vue)模板项目学习之路(一) C#程序中设置全局代理(Global Proxy) WCF 4.0 使用说明 如何在IIS上发布,并能正常访问
中小研发团队架构实践之生产环境诊断工具WinDbg 生产环境偶尔会出现一些异常问题,WinDbg或GDB是解决此类问题的利器.调试工具WinDbg如同医生的听诊器,是系统生病时做问题诊断的逆向分析工具 ...
- [转]linux 系统监控、诊断工具之 IO wait
1.问题: 最近在做日志的实时同步,上线之前是做过单份线上日志压力测试的,消息队列和客户端.本机都没问题,但是没想到上了第二份日志之后,问题来了: 集群中的某台机器 top 看到负载巨高,集群中的机器 ...
- Linux 下的一个全新的性能测量和调式诊断工具 Systemtap, 第 3 部分: Systemtap
Systemtap的原理,Systemtap与DTrace比较,以及安装要求和安装步骤本系列文章详细地介绍了一个Linux下的全新的调式.诊断和性能测量工具Systemtap和它所依赖的基础kprob ...
随机推荐
- 马昕璐201771010118 《面对对象程序设计(java)》第九周学习总结
第一部分:理论知识学习部分 异常:在程序的执行过程中所发生的异常事件,它中断指令的正常执行. Java把程序运行时可能遇到的错误分为两类: 非致命异常:通过某种修正后程序还能继续执行. 致命异常:程序 ...
- OpenCV常用头文件介绍
转载:https://www.cnblogs.com/wangguchao/p/7244483.html 1.OpenCV包含的模块 cv – 核心函数库 cvaux – 辅助函数库 cxcore – ...
- swust oj 1012
哈希表(链地址法处理冲突) 1000(ms) 10000(kb) 2542 / 6517 采用除留余数法(H(key)=key %n)建立长度为n的哈希表,处理冲突用链地址法.建立链表的时候采用尾插法 ...
- 记录k8s:k8s1.8.4无坑离线安装
安装部署: 1. 使用vagrant 准备3太虚拟机,自己使用Vbox 准备3太也可以. 2. 按照 https://github.com/gjmzj/kubeasz 安装. 3. 使用letsenc ...
- NeuChar 平台使用及开发教程(一):开始使用 NeuChar
如果您还不知道什么是 NeuChar,或者我们为什么要做 NeuChar,请看这里. 角色 NeuChar 打通了从开发者到终端用户的完整的上下游链路,了解 NeuChar 之前,先要明确两个角色身份 ...
- OSGi解决的问题
osgi最明显的缺陷 bundle尽管可以为隔离的服务建立独立生命周期管理的热部署方式,以及明确的服务导出和导入依赖能力,但是其最终基于jvm,无法对bundle对应的服务实现计算资源的隔离,一个服务 ...
- FFmpeg开发实战(五):FFmpeg 抽取音视频的视频数据
如何使用FFmpeg抽取音视频的视频数据,代码如下: // FFmpegTest.cpp : 此文件包含 "main" 函数.程序执行将在此处开始并结束. // #include ...
- 3种方法来在Linux电脑上查找文件
如果你不太了解Linux命令,那么在Linux系统里查找文件是比较困难的.只要使用多种不同的终端命令,可以很快地找到文件.Linux命令比其它操作系统的搜索功能更加强大,掌握这些命令就能你完全控制这些 ...
- [Java]LeetCode133. 克隆图 | Clone Graph
Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors. OJ's ...
- [Swift]LeetCode1002. 查找常用字符 | Find Common Characters
Given an array A of strings made only from lowercase letters, return a list of all characters that s ...