原文地址:http://www.cnblogs.com/mickeychang/archive/2009/08/29/1556527.html
.net 最佳实践一:监测.net代码中的高内存消耗函数
简介和目标
导致.NET 代码性能下降的重要因素之一是内存消耗。 许多开发人员只是主要用执行时间来确定.NET 应用程序的性能瓶颈。 只测量执行时间并不清楚知道性能问题之所在。 好,要说的和要做的一个最大任务就是知道哪些函数、 程序集或类占用了多少内存。 在本教程中,我们将看到我们如何找出哪些函数消耗多少内存。 本文讨论的最佳实践涉及使用 CLR 探查器(CLR profiler)研究内存分配。
请随时到 http://www.questpond.com下载我的涵盖.NET、 ASP.NET、 SQLServer、 WCF、 WPF、WWF的免费500个问题和回答的电子书。
非常感谢Peter Sollich先生
在开始本文时,首先要感谢CLR性能架构师Peter Sollich先生,他给CLR 探查器写了详细的帮助。当你安装CLR 探查器时不要忘记阅读Peter Sollich先生写的详细的帮助文档。
CLR Profiler to rescue
CLR探查器是一个帮助我们对.net代码监测内存分配情况的工具。CLR探查器由微软提供,你可以从下面的网址下载:
注意:CLR探查器有针对.net 1.1和2.0框架的两个版本。2.0框架的版本在http://www.microsoft.com/downloads/details.aspx?familyid=A362781C-3870-43BE-8926-862B40AA0CD0&displaylang=en,1.1的版本在http://www.microsoft.com/downloads/details.aspx?familyid=86ce6052-d7f4-4aeb-9b7a-94635beebdda&displaylang=en#Overview。
下载并解压CLR探查器之后,可以从bin目录下运行CLRProfiler.exe。
如果你下载的是2.0版本的CLR探查器,它提供针对X86和X64的两种执行环境,清确认你运行了正确的版本。
CLR探查器特性
如果你企图了解.net应用程序代码是如何 进行内存分配的,CLR探查器是最好的工具。它有两个重要的功能:
- <!--[if !supportLists]--> <!--[endif]-->给出一个.net应用程序是如何进行内存分配的报告。这样你就可以看到一个关于每一种数据类型,函数,和方法等是如何进行内存分配的完整报告。
- <!--[if !supportLists]--> <!--[endif]-->它同时也提供调用方法耗费的时间。
<!--[if !vml]--><!--[endif]-->
不应在产品中使用CLR探查器作为性能评估工具
CLR探查器是一嵌入工具,换句话说,它为应用程序内的每一个函数、类、模块在内存使用方面执行它自己的逻辑。比如说你有一个应用程序调用了函数1和函数2,当你使用CLR探查器探测应用程序时,它在每一个函数调用之后插入关于内存堆数据的使用情况,如下
<!--[if !vml]--><!--[endif]-->
换句话说,不要使用CLR探查器来查看你的应用程序的执行时间,它会减慢你的应用程序10到100倍,你会因错误的结果而死去。
如上所说,它是一个侵入式工具,你永远不要在你的产品环境中使用它。
第一,你永远不要一开始就用CLR探查器来分析你的性能问题。它更多的是用在第二步,在这里你可以调整一个有内存问题的函数或类。更可能的情况是首先使用性能计数器找到哪一个方法或函数的执行用了比较长的时间,然后再使用CLR探查器查看内存分配情况是怎么样的。
怎么运行CLR探查器
当你从微软网站下载CLR探查器后,把文件解压到一个目录中。转到解压后的目录下的Binaries目录,选择并运行‘CLRProfiler.exe’, CLR探查器运行如下图所示。
第一步要确定我们想探查什么,有两个探查选项,一是内存分配,另一是调用方法的次数,然后选择你要探查的数据,点击开始应用程序。
<!--[if !vml]--><!--[endif]-->
当完成之后,你会看到如下所示的探查结果的完整摘要。那是一个复杂的报告,当我们探查一个简单的应用程序时,我们想看到一个简化的结果。
<!--[if !vml]--><!--[endif]-->
使用CLR探查器面临的问题
运行CLR探查器时我们面临一些问题。如果我们看到了下面的界面,但它并没有结束,可能有两个原因:
- <!--[if !supportLists]--> <!--[endif]-->你的环境是.net 2.0,但你运行的CLR探查器是1.1的。
- <!--[if !supportLists]--> <!--[endif]-->你没有在GAC中注册ProfilerOBJ.dll。
<!--[if !vml]--><!--[endif]-->
我们要探查简单的应用程序
我们要探查的应用程序非常的简单,它有一简单的按钮,它调用函数‘UseSimpleStrings’ 和 ‘UseStringBuilders’。这两个函数都连接字符串,一个使用’+’连接,另一个使用‘StringBuilder’类,我们执行连接1000次。