[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());
}
}
}