记一个由gc引发的高cpu问题
记录我的windbg调试之旅。
问题描述:
有个项目cpu跳的厉害,马上请出windbg
1. adplus 抓包;
2. windbg打开文件,运行 .load sos ;
3. 运行 !threads, 发现进程 71 和 77 有异常,gc这项为disabled;
4. ~71s 切换到 该线程, !clrstack 查看托管代码,看看是哪个页面,看到页面是 imei_list.aspx;
5. !dso,发现有个string报告如下错误:
0:071> !dso
OS Thread Id: 0x11ec (71)
ESP/REG Object Name
1d1af0d4 156bd9e8 System.String <String is invalid or too large to print>
6. !objsize 得到如下结果,6.3M,不小的string啊,怪不得!do 打印不出来
0:071> !objsize 156bd9e8
sizeof(156bd9e8) = 6346824 ( 0x60d848) bytes (System.String)
7. 这次要看看代码了,打开项目,找到文件,这个文件业务很简单:获取某个用户的手机imei串列表,把所有的imei串拼接起来,然后输出,很简单,不该有什么问题啊,唯一的疑点,这个imei的列表有多大。
8. 连上数据库,打开过程,过程只有一条语句 select * from t_imei where userid = @userid, 如果userid = 0 会有多少数据呢,因为这个页面传进来的参数刚好和0,经查询,得到超过 6000条记录,难怪了。
现在终于明白了,因为这个也没的频繁访问(约1次/秒 ), 每次都会产生 6.3M的string,gc不断需要工作,导致了高cpu,简单改了程序和存储过程,一切ok了,cpu从40%下降到10%以下。