使用PerfView诊断.Net GC的问题
PerfView 概述:
PerfView是一个可以帮助你分析CPU和内存问题的工具软件。它非常轻量级也不会入侵诊断的程序,在诊断过程中对诊断的程序影响甚微。
Visual Studio自带的性能分析功能在CPU占用、时间消耗、内存分配等方面的诊断效果还算不错,但PerfView可以提供更加丰富的诊断分析信息。
在这篇文章中,我将使用PerfView给你展现如下功能:
- GC回收发生的频率以及回收所消耗的时间;
- 获取导致Large object分配的原因;
- 内存被谁占用了;
- 对比哪个托管对象增大的最快。
测试程序
现在我们准备一个将会导致内存泄露的程序,用来确保使用PerfView可以达到我们所期望的效果。它是一个WinForm应用程序,后台代码如下:
public partial class Form1 : Form
{
private List<int[]> arrays = new List<int[]>();
Random random = new Random(); public Form1()
{
InitializeComponent(); Thread thread = new Thread(Start);
thread.IsBackground = true;
thread.Start();
} private void Start(object obj)
{
while (true)
{
int[] a = new int[random.Next(, )];
arrays.Add(a);
Thread.Sleep();
}
}
}
使用PerfView进行跟踪
开启PerfView,你将会看到如下窗口:

PerfView的使用手册被集成在这个程序中,你可以菜单栏来进行访问。
然后点击菜单“Collect-->Collect”来进行数据采集,用来分析生成诊断结果:

无需修改任何初始化配置,点击“Start Collection”按钮,PerfView将会开始采集所有进程的事件数据。
数十秒之后,你可以点击“Stop Collection”按钮,PerfView将会停止采集并生成诊断文件“PerfViewData.etl.zip”:

获取GC Stats
双击“GCStats”报表,将会弹出一个窗口,窗口中显示了每一个进程GC信息,找到我们的测试程序。
关于测试程序我们将会得到如下汇总信息表:

进一步往下看,还会显示GC触发的原因:

如上图所示,这次GC的collection的发生是因为large object的分配。
获取导致large object分配的原因
从PerfView的主界面,双击打开“GC Heap Alloc Stacks”窗口,然后双击测试程序的进程,之后弹出的窗口将根据内存分配从大到小的次序显示堆栈信息:

PerfView会将所有的large object分配都归类在LargeObject节点下面,双击该节点可以看到如下信息:

备注:如果你在上图所示的界面中看到“OTHER<<clr?>>”,可以对其鼠标右击,然后点击“Lookup Symbols”,来获取CLR和Windows的功能名称。
上图中主要列的说明如下:
Inc%:表示该对象分配的字节占所有记录分配的百分比;
Inc:该对象分配字节的总数;
Inc Ct:该对象分配的次数。
从上图可以看出,巨多的large object都是来自Start方法的Int32数组,PerView精确地诊断出我们预期的效果。
谁造成了内存泄露
PerfView可以通过heap dump来查看占用内存的对象的路径。
从主界面点击菜单项“Memory-->Tale Heap Snapshot”,弹出窗口如下图所示:

找到我们的测试程序并选中,然后点击“Dump GC Heap”按钮,数秒后再点击“CLose”按钮,最后会生成一个“.gcdump”文件。

双击打开“WindowsFormsApplication1.gcdump”窗口,显示如下所示:


PrefView精确地诊断出,是static variables占用了内存。
使用两个Heap Dump来查看对象所占内存的变化情况
在应用程序连续运行的情况下,对其进行两次Take Heap Sanpshot,确保两次生成的文件名称不一致。同时打开这两个.gcdump文件的窗口,通过任一一个窗口的diff菜单项功能,都能以另一个窗口的数据为基准进行对比。
使用PerfView诊断.Net GC的问题的更多相关文章
- 每周.NET前沿技术文章摘要(2017-05-17)
汇总国外.NET社区相关文章,覆盖.NET ,ASP.NET等内容: .NET .NET Framework 4.7正式发布 链接: http://www.infoq.com/cn/news/2017 ...
- PerfView专题 (第七篇):如何洞察触发 GC 的 C# 代码?
一:背景 上一篇我们聊到了如何用 PerfView 洞察 GC 的变化,但总感觉还缺了点什么? 对,就是要跟踪到底是什么代码触发了 GC,这对我们分析由于 GC 导致的 CPU 爆高有非常大的参考价值 ...
- .NET内存性能分析宝典
.NET Memory Performance Analysis 知道什么时候该担心,以及在需要担心的时候该怎么做 译者注 **作者信息:Maoni Stephens ** - 微软架构师,负责.NE ...
- Java 应用性能调优实践
Java 应用性能优化是一个老生常谈的话题,笔者根据个人经验,将 Java 性能优化分为 4 个层级:应用层.数据库层.框架层.JVM 层.通过介绍 Java 性能诊断工具和思路,给出搜狗商业平台的性 ...
- Java程序进行调优及监控
Java 应用性能的瓶颈点非常多,比如磁盘.内存.网络 I/O 等系统因素,Java 应用代码,JVM GC,数据库,缓存等.笔者根据个人经验,将 Java 性能优化分为 4 个层级:应用层.数据库层 ...
- 面试官问我:平常如何对你的 Java 程序进行调优?
阅读本文大概需要 10 分钟. 作者:张俊城, 郭理勇, 刘建来源:http://t.cn/AiCTERJz Java 应用性能优化是一个老生常谈的话题,典型的性能问题如页面响应慢.接口超时,服务器负 ...
- [转载]Java 应用性能调优实践
Java 应用性能调优实践 Java 应用性能优化是一个老生常谈的话题,笔者根据个人经验,将 Java 性能优化分为 4 个层级:应用层.数据库层.框架层.JVM 层.通过介绍 Java 性能诊断工具 ...
- 你的JVM还好吗?GC初步诊断
你的JVM还好吗?GC初步诊断 阿飞的博客 JVM的GC机制绝对是很多程序员的福音,它让Java程序员省去了自己回收垃圾的烦恼.从而可以把大部分时间专注业务身上,大大提高了业务开发速度,让产品 ...
- 如何诊断RAC系统中的'gc cr multi block request'?
'gc cr multi block request' 是RAC数据库上比较常见的一种等待事件,在RAC 上进行全表扫描(Full Table Scan)或者全索引扫描(Index Fast Full ...
随机推荐
- kernel/ptrace.c
/* ptrace.c *//* By Ross Biro 1/23/92 *//* edited by Linus Torvalds */ #include <linux/head.h> ...
- oracle rman恢复数据库 方式恢复到异地数据库
目的:从某个环境中,获取相关文件,放到异地机器使用rman 恢复. 情况说明:XX系统使用的是oracle数据库,现已从服务器拉下来相关文件,依靠这些文件来早本地的测试机上恢复数据库,方便进行数据 ...
- 浏览器与web客户端的HTTP交互过程
未经许可谢绝以任何形式对本文内容进行转载! HTTP协议是常见的几种应用层协议之一,当我们用浏览器和web客户端进行交互时html页面等内容的传输都是依靠该协议完成的.值得注意的是,HTTP使用的是T ...
- ACM water
1000 纯属适应题 1003 做的时候花了很久,现在看好像也不难 1004 适应题,求下平均就行 1005 要读懂题就行 1007 逆序数,discuss方法 1046 全部暴搜一遍.. ...
- python-print
%s,%d就是占位符.还有%r 只是说明这样的对应:%s-->str();%r-->repr(),什么意思呢?就是说%s调用的是str()函数把对象转化为str类型,而%r是调用了repr ...
- Rails : css或js文件无法成功预编译或调用jquery类插件时预编译问题
调用bootstrap css框架时,将bootstrap文件夹放入 vendor/assets/下 bootstrap文件结构如下: [shenma@localhost demo]$ ls v ...
- [经验交流] Kubernetes Nginx Ingress 安装与使用
Ingress 介绍 Kubernetes 上部署的微服务运行在它的私有网络中, 通过Pod实例的hostPort或Service实例的NodePort可以暴露到主机端口上,便于用户访问.但这样的方法 ...
- python 中__name__ = '__main__' 的作用
有句话经典的概括了这段代码的意义: "Make a script both importable and executable" 意思就是说让你写的脚本模块既可以导入到别的模块中用 ...
- if、if elif判断
1.if.py #coding=utf-8 user = 'alex' passwd = 'alex3714' username = input('username:') password = inp ...
- ASP.NET在IIS7.5(IIS7)配置伪静态
http://jingyan.baidu.com/article/67508eb4ff92c69cca1ce49a.html 我相信不少站长都遇到个头疼的问题..NET如何在IIS7或者IIS7.5下 ...