文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>[ASP.NET Debugging BuggyBits读书笔记] Lab04 High CPU Hang

[ASP.NET Debugging BuggyBits读书笔记] Lab04 High CPU Hang

时间:2011-01-17  来源:李志鹏

2. 使用TinyGet执行 tinyget srv:localhost –uri:/buggybits/AllProducts.aspx –threads:5 –loop:1

3. 在WinDbg目录执行 adplus –hang –pn w3wp.exe –quiet

4. 使用WinDbg打开第三步生成的.dmp文件,执行 .loadby sos.dll mscorwks

5. 执行 !threadpool 查看当前生成dmp时的CPU利用率 :

可见当前CPU利用率为100%

6. 执行 !runaway查看没有线程占用的CPU时间:

可见占用CPU时间最多的是线程18。

7. 切换到该线程,执行~18s。然后执行 !clrstack 查看该线程执行到了什么地方:

可见程序在Page_load方法里卡住了。找到这条指令所在地址 075f09c9

8. 执行 !u 075f09c9进行反汇编:

怀疑程序是在进行字符串构造。

9. 执行 !dso 查看该线程相关的object,找到大量的字符串对象。

10. 查看程序源代码AllProducts.aspx.cs:

可见程序直接使用了 + 进行字符串连接。这正好与System.String.Concat方法契合。

由于直接将字符串进行相连,会导致之前分配字符串对象的存储空间被废弃,CLR必须为新的字符串对象分配新的空间,这就导致CLR忙于分配字符串空间,造成high CPU。比如下例:

class Program
{
    static void Main(string[] args)
    {
        string s = null;
        for (int i = 0; i < 100000; i++)
        {
            s = s + i.ToString();
        }
    }
}
运行之后可以直接在Task Manager里看到CPU占用率的直线上升。

对此的解决办法是使用StringBuilder:

class Program
{
    static void Main(string[] args)
    {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 100000; i++)
        {
            sb.Append(i.ToString());
        }
    }
}

这样当有新的String声称之后,旧有的string会在原对象大小的基础分配一个大小为原对象大小两倍的对象。这样就避免CLR反复消耗于分配新的对象。
相关阅读 更多 +
排行榜 更多 +
找茬脑洞的世界安卓版

找茬脑洞的世界安卓版

休闲益智 下载
滑板英雄跑酷2手游

滑板英雄跑酷2手游

休闲益智 下载
披萨对对看下载

披萨对对看下载

休闲益智 下载