Memory Dump 分析器
Visual Studio 2013 新功能 Memory Dump 分析器
TechEd2013 发现新功能
12月5日和6日,在国家会议中心参加了微软的 TechEd2013 技术大会,了解了很多微软所提供的软件新功能和新技术。





在上面的图中描述了在 Visual Studio 2013 中提供了新的功能 .NET Memory Dump Analysis,在具体的 Visual Studio 2013 新功能介绍的 Session 看到了实际的演示。当时感觉这个新功能对开发人员太有帮助了,因为使用 WinDbg 进行内存泄漏等问题排查总是一种痛苦。如果能在 Visual Studio 中包含类似的功能就再好不过了。
准备尝鲜 .NET Memory Dump Analysis
回到家,自然是想使用 Visual Studio 2013 直接上手实际体验下。
在创造了一个 Dump 文件之后,使用 Visual Studio 2013 直接打开,

结果发现,在 Actions 处少一个 "Debug Managed Memory" 按钮。

它应该长这个样子才对:

Google 之后发现原来我使用的是 Visual Studio 2013 Premium 版本,而该功能只有在 Visual Studio 2013 Ultimate 版本中才支持。

公司的 MSDN 订阅选的是 Premium ,比较了下与 Ultimate 的区别,价格果真差的很大。

此时,我选择了安装个 Windows 7 SP1 虚拟机,并安装 Visual Studio 2013 Ultimate 的试用版。
遭遇 Visual Studio 2013 的 Known Issue
显然,安装上 Visual Studio 2013 Ultimate 之后,再打开 Dump 文件,就可以成功看到 Actions 中的 "Debug Managed Memory" 按钮。
点击该按钮,等待 Heap View 显示。
什么?白屏?一万只马飘过。

这可真是郁闷,折腾了半天都没反应。
于是只能问 Google 了,显然,新的功能暂时没什么人用,也搜不到什么有用的讨论。
终于,当搜索关键词修改为 “Visual Studio 2013 Debug Managed Memory is not work” 时,有用的信息出现了。

打开一看,这居然是一个 Visual Studio 2013 Known Issue,基本就是要求安装 IE10 或以上的版本才能使用此功能。

解决办法,当然就是安装新版 IE,立马下载安装 IE11。新装的虚拟机中的 Windows 7 默认的还是 IE8 。
使用 Dump 文件比较功能
这一次,成功看到了 Heap View。

在 Compare to 中选择一个之前的 Dump 文件作为对比,即可查看两个文件时间的内存变化。

Inclusive Size
在 Heap View 中,有一列为 Inclusive Size (Bytes)。

其包含所显示对象引用的所有对象内存占用的总和。下面的图标展示了内存占用大小的计算过程。

|
Object Type |
Count |
Size (Bytes) |
Inclusive Size (Bytes) |
|
Customer |
1 |
100 |
400 |
|
Address |
1 |
50 |
200 |
|
String |
2 |
150 |
150 |
|
Byte[] |
1 |
100 |
100 |
Address 对象的 Inclusive Size = Address (50 bytes) + String (50 bytes) + Byte[] (100 bytes) = 200 bytes
Customer 对象的 Inclusive Size = Address Inclusive Size (200 bytes) + String (100 bytes) + Customer (100 bytes) = 400 bytes
Inclusive Size Diff
在使用 Dump 比较功能后,显示的列中会出现 "Inclusive Size Diff",用来描述在两个 Dump 文件采集的时间点时,Inclusive Size 的变化。

View Setting
在 Dump 比较的界面中,我们可以看到 View Settings 选项。

- Just My Code :顾名思义,仅显示用户代码。
- Collapse Small Objects :隐藏小对象。
这里需要描述下,小对象隐藏后的 Inclusive Size 的计算方式。
实际上,会将被隐藏的小对象的大小累加到父对象上。
仍然使用上面的图例进行计算。

我们假设 String 和 Byte[] 被隐藏,在隐藏小对象后,

|
Object Type |
Count |
Size (Bytes) |
Inclusive Size (Bytes) |
|
Customer |
1 |
200 |
400 |
|
Address |
1 |
200 |
200 |
Paths To Root View
点击 Heap View 列表中的某一个 Object Type,在 Paths To Root 中会通过级联方式显示对象的引用关系。
这用于显示,是哪个对象引用导致该对象没有被垃圾回收。

References View
References View 用于显示,这个对象都引用了哪些对象。

测试用代码

1 using System;
2 using System.Collections.Concurrent;
3 using System.Collections.Generic;
4 using System.Threading;
5
6 namespace TestDebugMemoryDumpFile
7 {
8 class Program
9 {
10 static ConcurrentQueue<Tree> _leakedTrees = new ConcurrentQueue<Tree>();
11
12 static void Main(string[] args)
13 {
14 List<string> fruits = new List<string>() // 6 items
15 {
16 "Apple", "Orange", "Pear", "Banana", "Peach", "Hawthorn",
17 };
18
19 Random random = new Random();
20 while (true)
21 {
22 string fruitName = fruits[random.Next(0, 5)];
23 Tree fruitTree = new Tree(fruitName);
24 BuildFruitTree(fruitTree, 100); // 100M
25 _leakedTrees.Enqueue(fruitTree);
26
27 Console.WriteLine("Added [{0}] on [{1}]...",
28 fruitTree.Name,
29 DateTime.Now.ToString(@"yyyy-MM-dd HH:mm:ss.ffffff"));
30
31 Thread.Sleep(TimeSpan.FromSeconds(5));
32 }
33 }
34
35 private static void BuildFruitTree(Tree fruitTree, int leafCount)
36 {
37 Console.WriteLine("Building [{0}] on [{1}]...",
38 fruitTree.Name,
39 DateTime.Now.ToString(@"yyyy-MM-dd HH:mm:ss.ffffff"));
40
41 for (int i = 0; i < leafCount; i++) // size M
42 {
43 Leaf<byte[]> leaf = new Leaf<byte[]>(Guid.NewGuid())
44 {
45 Content = CreateContentSizeOfOneMegabyte()
46 };
47 fruitTree.Leaves.Add(leaf);
48 }
49 }
50
51 private static byte[] CreateContentSizeOfOneMegabyte()
52 {
53 byte[] content = new byte[1024 * 1024]; // 1 M
54 for (int j = 0; j < content.Length; j++)
55 {
56 content[j] = 127;
57 }
58 return content;
59 }
60 }
61
62 internal class Tree
63 {
64 public Tree(string name)
65 {
66 Name = name;
67 Leaves = new List<Leaf<byte[]>>();
68 }
69
70 public string Name { get; private set; }
71 public List<Leaf<byte[]>> Leaves { get; private set; }
72 }
73
74 internal class Leaf<T>
75 {
76 public Leaf(Guid id)
77 {
78 Id = id;
79 }
80
81 public Guid Id { get; private set; }
82 public T Content { get; set; }
83 }
84 }

参考资料
Memory Dump 分析器的更多相关文章
- Visual Studio 2013 新功能 Memory Dump 分析器
本文为 Dennis Gao 原创技术文章,发表于博客园博客,未经作者本人允许禁止任何形式的转载. TechEd2013 发现新功能 12月5日和6日,在国家会议中心参加了微软的 TechEd2013 ...
- Responder Pro new version could analyze Win10 memory dump
My friend John acquired a memory dump from Windows 10, but he could analyze this memory dump with an ...
- qualcomm memory dump 抓取方法
Memory dump是系统出现crash时常用的分析故障原因的方法,qualcomm 各子系统运行时,为方便debug,都会开辟ram log和debug variable用于保存各系统运行信息及健 ...
- How do I find what queries were executing in a SQL memory dump?-----stack
https://blogs.msdn.microsoft.com/askjay/2010/10/03/how-do-i-find-what-queries-were-executing-in-a-s ...
- 利用 Memory Dump Diagnostic for Java (MDD4J) 分析内存管理问题
利用 Memory Dump Diagnostic for Java (MDD4J) 分析内存管理问题(2) 启动和理解 MDD4J[size=1.0625]为了充分理解如何使用 MDD4J,您需要了 ...
- memory dump and CLR Inside Out
MSDN Magazine: CLR Inside Out https://msdn.microsoft.com/en-us/magazine/cc501040.aspx CLR Inside Out ...
- Android memory dump
1.读取指定pid和内存地址的字符: #include <stdlib.h> #include <stdio.h> #include <string.h> #inc ...
- .NET Memory Profiler 查看内存使用情况
1 简介 .Net Memory Profiler(以下简称Profiler):专门针对于.NET程序,功能最全的内存分析工具,最大的特点是具有内存动态分析(Automatic Memory Anal ...
- SharePoint运行状况分析器有关磁盘空间不足的警告
对于负责管理SharePoint内部部署安装的SharePoint管理员,SharePoint Health Analyzer是一款出色的工具.此功能不仅有助于解决服务器故障和服务失败的问题,还提供了 ...
随机推荐
- 用Markdown来写作
Markdown 是一种简单的.轻量级的标记语法.github上面很多的README就是用markdonw语法写的. Markdown 的语法十分简单,常用的标记符号也不超过十个,且一旦熟悉这种语法规 ...
- 博客测试:博客系统i94web beta1.0 申请测试
如何做了最近的博客更新,因为已经在线路和代码,我写了一个小博客系统:i94web,草草宣布beta1.0,请求您测试各种漏洞. 先看几张截图. 首页: watermark/2/text/aHR0cDo ...
- [WF4.0 实战] WPF + WCF + WF 打造Hello World(基础篇)
本篇博客是一个基础的演示样例,也就是一个新手教程吧!让大家熟悉一下WPF + WCF + WF三者的关系!这仅仅是一个基础篇,下篇会继续深入,作为这段时间研究工作流的一个小小总结! 三者关系: WPF ...
- 注册 集 与 删除 -- C
文章3位设置和清除操作. #include <stdio.h> #include <stdlib.h> #include <string.h> #define BI ...
- C# Parse和Convert的区别分析
原文:C# Parse和Convert的区别分析 大家都知道在进行类型转换的时候有连个方法供我们使用就是Convert.to和*.Parse,但是疑问就是什么时候用C 什么时候用P 通俗的解释大家都知 ...
- PHP_零基础学php_3PHP函数、传参函数、默认参数、函数返回值
<?php function say_hello() //无参数 { $name="tang"; echo "hello,".$name; echo &q ...
- Cocos2d-xvision3.0加载失败,和,Vs2012环境搭建
1.安装好VS2012,下载Cocos2d-x3.0 双击击win32 sln运行VS2012 如果加载失败点击程序运行,输入devenv.exe /resetuserdata 回车,然后再进入VS, ...
- 三星GT-S7572换屏幕教程
家里人手机被摔坏了,尽管不是什么值钱的手机.可是自从上了大学之后,就一直认为赚钱真的非常不easy,不到逼不得已,就不要乱花钱.于是,就从淘宝上买了外屏.以下是我在淘宝上的链接:点击打开链接.好不ea ...
- ARC注意的泄漏问题
--------- block中常见的泄漏问题 代码中block经常用到.例如网络请求?一些图形分析处理等,就是比较耗时的操作,多线程gcd然后进行操作. 这个时候,会使用block进行处理,然后调用 ...
- 蓝色的成长记录——追逐DBA(8):为了夺回SP报告,回顾oracle的STATSPACK实验
***********************************************声明*************************************************** ...