微软提供了标准的CLR性能分析类库

https://github.com/Microsoft/clrmd

这个类库是开源的代码。能够获取CLR runtime里面几乎所有的信息。

如何获取clrmd编译后的dll

方法一

在nuget里面搜索clrmd可以很方便的下载

方法二

估计有些同学和我一样喜欢手动挡,那么我这里提供一个下载dll的地址。项目里面只要引用这个dll就能对CLR进行分析诊断了。

https://raw.githubusercontent.com/wsq003/clrmd/master/bin/Microsoft.Diagnostics.Runtime.dll

如何分析CPU消耗

原理

1、操作系统能够记录每个os thread的cpu消耗

2、CLR的managed thread和操作系统的os thread会动态的进行映射

3、通过clrmd可以获取每个managed thread的call stack

4、结合123我们可以分析出asp.net里面那个线程的代码消耗了最多CPU

思路

在asp.net项目里面新增一个‘一般处理程序ashx’页面,比如diagnose.ashx,在这个页面代码里面记录每个os thread的cpu消耗,每个managed thread的call stack,以及os thread和managed thread的对应关系。

反复调用diagnose.ashx,看看最忙的那个os thread是被哪个managed thread占用的。

参考代码

public void ProcessRequest(HttpContext context)
{
    context.Response.ContentType = "text/plain";

    {
        int pid = System.Diagnostics.Process.GetCurrentProcess().Id;
        var msg = GetCallstack(pid);
        context.Response.Write(msg);
    }

    var ths = Process.GetCurrentProcess().Threads;
    foreach (ProcessThread th in ths)
    {
        var msg = string.Format("{0}-{1:0.0}, {2:0.0}, {3:0.0}\r\n",
            th.Id, th.TotalProcessorTime.TotalSeconds, th.PrivilegedProcessorTime.TotalSeconds, th.UserProcessorTime.TotalSeconds);

        context.Response.Write(msg);
    }
}

string GetCallstack(int pid)
{
    try
    {
        using (var dataTarget = DataTarget.AttachToProcess(pid, 5000, AttachFlag.Passive))
        {
            var runtime = dataTarget.ClrVersions[0].CreateRuntime();

            string info = "";
            foreach (var t in runtime.Threads)
            {
                var cs = t.StackTrace.Select(f =>
                {
                    if (f.Method != null)
                    {
                        return f.Method.Type.Name + "." + f.Method.Name;
                    }

                    return null;
                }).ToArray();

                if (cs.Length > 0)
                {
                    info += string.Format("系统线程ID:{0} - CLR线程ID{1}:\r\n", t.OSThreadId, t.ManagedThreadId);

                    foreach (var line in cs)
                    {
                        info += string.Format("{0}\r\n", line);
                    }
                    info += "\r\n";
                }
            }

            return info;
        }

    }
    catch (Exception ex)
    {
        return "获取callstack失败:" + ex.Message;
    }
}

补充说明

因为.net framework rumtime的版本问题,要用一个单独的工具去attach其他进程做分析,是很困难的。

如果想为C#做一个独立的易用的性能诊断工具,可以参考java世界的jvmti。让被诊断的进程自己暴露一个接口,把clr的各种诊断数据都吐出来。

[C#] 网站程序ASP.NET的性能诊断 - CPU分析的更多相关文章

  1. 使用vs自带的性能诊断工具

    visual studio是个强大的集成开发环境,内置了程序性能诊断工具.下面通过两段代码进行介绍. static void Main( string[] args) { Test1(); Test2 ...

  2. 【渗透课程】特别篇-主流网站程序Oday大全以及拿shell思路

    版权和内容说明: 这篇文章不是本站编写,是从网络上摘抄的,但是经过了本站的改写优化,并将内容,格式规范化. 本篇说明:这篇文章结合了前辈们前几年一路挖掘出来的主流程序漏洞以及思路, 小编写在前面是想让 ...

  3. ASP.NET网站与ASP.NET应用程序的区别

    我们使用VS做ASP.NET的时候,可以选择新建ASP.NET应用程序,同时也可以新建ASP.NET网站,两者有什么具体区别呢?今天真是很幸运,比别人多上了老师一节课,讲的是这两者之间的一些区别.我学 ...

  4. ASP.Net网站程序在编译发布部署后的后期修改

    ASP.Net网站程序在发布部署后的后期修改 作者:东篱南山 这里说的后期修改是指网站编译发布并部署好之后,对程序进行的修改,即在不能更改现有代码的情况下,更改页面的显示或是更改业务逻辑.一般是在程序 ...

  5. C# -- HttpWebRequest 和 HttpWebResponse 的使用 C#编写扫雷游戏 使用IIS调试ASP.NET网站程序 WCF入门教程 ASP.Net Core开发(踩坑)指南 ASP.Net Core Razor+AdminLTE 小试牛刀 webservice创建、部署和调用 .net接收post请求并把数据转为字典格式

    C# -- HttpWebRequest 和 HttpWebResponse 的使用 C# -- HttpWebRequest 和 HttpWebResponse 的使用 结合使用HttpWebReq ...

  6. 如何利用IIS调试ASP.NET网站程序详解

    如何利用IIS调试ASP.NET网站程序详解 更新时间:2019年01月13日 08:44:13   作者:江湖逍遥    我要评论   这篇文章主要给大家介绍了关于如何利用IIS调试ASP.NET网 ...

  7. 60,000毫秒内对Linux的性能诊断效的方法

    转载于:http://www.itxuexiwang.com/a/liunxjishu/2016/0225/168.html?1456484140 60,000 毫秒内对 Linux 的性能诊断 当你 ...

  8. ASP.NET26个性能优化方法

    1.数据库访问性能优化 (1)数据库的连接和关闭 访问数据库资源需要创建连接.打开连接和关闭连接几个操作.这些过程需要多次与数据库交换信息以通过身份验证,比较耗费服务器资源. ASP.NET中提供了连 ...

  9. (摘录)26个ASP.NET常用性能优化方法

    数据库访问性能优化 数据库的连接和关闭 访问数据库资源需要创建连接.打开连接和关闭连接几个操作.这些过程需要多次与数据库交换信息以通过身份验证,比较耗费服务器资源. ASP.NET中提供了连接池(Co ...

随机推荐

  1. BZOJ 3992 【SDOI2015】 序列统计

    题目链接:序列统计 我来复习板子了……这道题也是我写的第一发求原根啊? 求原根方法: 从小到大依次枚举原根.设当前枚举的原根为\(x\),模数为\(p\),\(p-1\)的质因数分别为\(p_1,p_ ...

  2. 转发一篇分析LinQ是什么?

    LINQ(发音:Link)是语言级集成查询(Language INtegrated Query) ?LINQ是一种用来进行数据访问的编程模型,使得.NET语言可以直接支持数据查询 ?LINQ的目标是降 ...

  3. [Java学习] Java虚拟机(JVM)以及跨平台原理

    相信大家已经了解到Java具有跨平台的特性,可以“一次编译,到处运行”,在Windows下编写的程序,无需任何修改就可以在Linux下运行,这是C和C++很难做到的. 那么,跨平台是怎样实现的呢?这就 ...

  4. nyoj1272表达式求值(递归法)

    递归写的,类似于之前的一道,但要更难一点,因为加入了'+','*'以及括号运算符,所以要考录周全: 这道题给了我很大启示,在第一道德基础上: 1!寻找括号的优先级,先找有没有不被任何括号夹住的加号,如 ...

  5. 计时(.NET)

    using System.Diagnostics; // 开始计时 Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); // 要计时的操 ...

  6. DB2默认的事务及并发锁机制

    今天有点时间,试验了一下DB2的并发锁机制,结果,和MSSQL的差不多:1.DB2的缺省行为,事务以可执行的SQL开始,以COMMIT或ROLLBACK结束:2.DB2缺省是否提交,以工具的不同而不同 ...

  7. [LeetCode] 268. Missing Number ☆(丢失的数字)

    转载:http://www.cnblogs.com/grandyang/p/4756677.html Given an array containing n distinct numbers take ...

  8. 最全的CSS浏览器兼容问题【CSS技巧 】

    CSS对浏览器的兼容性有时让人很头疼,或许当你了解当中的技巧跟原理,就会觉得也不是难事,从网上收集了IE7,6与Fireofx的兼容性处理方法并整理了一下.对于web2.0的过度,请尽量用xhtml格 ...

  9. delphi image控件上画矩形的问题

    画的时候发现鼠标点的位置和矩形的位置有偏移 后来查看发现是由于image控件时stretch属性设置为true,这样在画的时候是缩放了的 也就是画到image显示的图片上去了 所以如果要画矩形,要按照 ...

  10. 返回值为record类型的函 初始化 内存泄漏 复制

    1.函数需要初始化,否则下次调用函数时,Result还是上次的值,可能会引起误判.但是不会有内存泄漏,即使包含string类型的成员. 2.如果record包含的都是值类型的成员,比如integer, ...