基本的概述

在一个服务器的集群上面,服务器的CPU长时间居高不下,响应的时间也一直很慢,即使扩容了服务器CPU的下降效果也不是很明显。

对于CPU过高的原因,可以总结到以下原因:

  • 太多的循环或者死循环

  • 加载了过多的数据,导致产生了很多的大对象

  • 产生了过多的对象,GC回收过于频繁(如:字符串拼接)

对于上面的情况,难点不是优化代码,难点在于定位到问题的所在,下面我们就用Dump抓包的方式来定位到问题的所在。介绍这个内容之前,我们要先回顾下.Net中垃圾回收的基础知识和一个工具的准备。


基础知识


垃圾回收触发条件

  • 代码显示调用System.GC的静态方法

  • windows报告低内存情况

  • CLR正在卸载AppDoamin

  • CLR正在关闭

大对象垃圾回收

CLR将对象分为大对象和小对象,认为大于85000字节或者更大的字节是大对象,CLR用不同的方式来对待大对象和小对象:

  • 大对象不是在小对象的地址空间分配,而是在进程地址空间和其他地方分配

  • GC不会压缩大对象,在内存中移动他们的代价过高,但这样会造成地址空间的碎片化,以至于会抛出OutOfMemeryException 异常。

  • 大对象总是在第二代回收。

工具准备

  1. 下载windbg文件

  2. 相关DLL准备clr.dll和sos.dll,(都在对应.Net版本安装目录下面,我的安装目录在C:\Windows\Microsoft.NET\Framework64\v4.0.30319)

  3. 一个cpu运行的较高的时期的DUMP文件(下面会说如何获取)

  4. 准备测试代码,此处为了演示方便,简单了写了一个有潜在问题的代码:

public  class Common
{
public static List<string> GetList()
{
var list=new List<string>();
for (int i = 0; i < 10000; i++)
{
list.Add(i.ToString());
}
return list;
} public static string GetString(List<string> list)
{
var str = "";
foreach (var l in list)
{
str += string.Format("'{0}',", l);
}
if (str.Length > 0)
{
str.Remove(str.Length - 1);
}
return str;
}
}

我们知道在字符串的拼接的时候,每一个字符串都是一个对象,拼接后又产生了一个新对象,所以在GetString这个方法中会有大量的GC操作,下面我们就调用下这个代码,看下CPU的情况,为了模拟并发情况,我们开多个标签,每个标签每1s秒中刷新一次。

抓取Dump

在任务管理器中选择应用程序池对应的w3wp.exe,右击–>创建转储文件。创建完成后,会提示出指定的路径

根据上面的步骤,我们准备我们分析的文件如下:

分析Dump

  • 打开windbg,加载对应的dump文件

  • 配置Sysmbol,添加”cachec:\mysymbol;srvhttp://msdl.microsoft.com/download/symbols” 

  • load sos.dll和clr.dll,命令如下:
      .load D:\windbg\sos.dll
    .load D:\windbg\clr.dll
  • 运行命令!threadpool 显示有关托管线程池的信息,其它一些SOS 调试扩展命令.

  • 运行!runaway 查询cpu占用时长比较长的几个线程Id

  • 运行~22s (进入线程查看),kb(查看对应的调用)

  • 运行~* kb 查看所有线程的堆栈调用

  • 在上面搜索GC和大对象出现的线程 (ctrl+f搜索:GarbageCollectGeneration和allocate_large_object )

  • 可以看到定位触发GC的线程是31号线程

  • 运行命令~31s 进入31线程,再运行!clrstack查看堆栈调用,最终可以定位到出问题的代码,是由于字符串的拼接导致大量的对象产生,从而触发了GC。

服务器CPU居高不下--解决问题历程的更多相关文章

  1. 服务器CPU使用率高的原因分析与解决办法

    我们的服务器在使用操作系统的时候,用着用着系统就变慢了,打开“ 任务管理器 ”一看,才发现CPU使用率达到80%以上.这是怎么回事情呢?遇到病毒了吗?硬件有问题?还是系统设置有问题呢?在本文中将从硬件 ...

  2. Linux服务器CPU、内存、磁盘空间、负载情况查看python脚本

    [本文出自天外归云的博客园] 网上搜,东拼西凑,组装了一个可以查Linux服务器CPU使用率.内存使用率.磁盘空间占用率.负载情况的python脚本. 脚本内容如下: # -*- coding:utf ...

  3. 实际遭遇GC回收造成的Web服务器CPU跑高

    今天下午有段时间访问园子感觉不如以前那么快的流畅,上Web服务器一看,果然,负载均衡中的1台云服务器CPU跑高. 上图中红色曲线表示的是CPU占用率.正常情况下,CPU占用率一般在40%以下. 这台云 ...

  4. 【故障公告】再次出现数据库 CPU 居高不下的问题以及找到问题的线索

    非常非常抱歉,今天上午的故障又一次给大家带来麻烦了,再次恳请大家的谅解. 在昨天升级阿里云 RDS SQL Server 实例的配置后(详见昨天的博文),万万没有想到,今天上午更高配置的阿里云 RDS ...

  5. 【故障公告】数据库服务器 CPU 近 100% 引发的故障(源于 .NET Core 3.0 的一个 bug)

    非常抱歉,这次故障给您带来麻烦了,请您谅解. 今天早上 10:54 左右,我们所使用的数据库服务(阿里云 RDS 实例 SQL Server 2016 标准版)CPU 突然飙升至 90% 以上,应用日 ...

  6. 【转帖】处理器史话 | 服务器CPU市场的战役, AMD、Intel和ARM的厮杀

    处理器史话 | 服务器CPU市场的战役, AMD.Intel和ARM的厮杀 https://www.eefocus.com/mcu-dsp/377300   说完了个性鲜明的消费类电子,接下来聊一聊通 ...

  7. 如何优雅排查现网服务器cpu飙高的问题

    1.排查现网服务器cpu飙高问题的思路 1.查看java进程id ps -ef|grep java 2.使用top -Hp 进程id 查看cpu比较高的线程 3.执行jstack 进程id > ...

  8. asp.net mvc4 简单的服务器监控开发之C#获取服务器CPU、RAM、TCP等系统信息(上)

    一.背景 前段时间服务器出了点问题,加上学业愈来愈紧张,写博文分享的时间越来越少.虽然不是第一次在博客园上写经验,但是近期分享的博文得到了不少的朋友支持和指正,在这里内心非常感激和开心.希望以后能认真 ...

  9. [故障公告] 13:52-14:03,访问量突增,博客web服务器CPU 100%

    13:52-14:03,由于访问量突增,博客web服务器全线CPU 100%,造成博客站点不正常访问,由此给您带来麻烦,请您谅解. 为了迎接访问量的增长给web服务器CPU带来的巨大压力,上周我们已经 ...

随机推荐

  1. 64位版本为什么叫amd64,而不是intel64

    64位版本为什么叫amd64,而不是intel64? 首先了解下常见的几个架构: X86是一个指令集,是刚有个人电脑时候的什么8086,286,386的那个兼容的指令集.   “x86-64”,有时会 ...

  2. session和cookie相关知识总结

    HTTP协议本身是无状态的,这与HTTP协议本来的目的是相符的,客户端只需要简单的向服务器请求下载某些文件,无论是客户端还是服务器都没有必要纪录彼此过去的行为,每一次请求之间都是独立的. 人们很快发现 ...

  3. Win7 VS2015 NASM汇编语言环境配置

    参考了以下两个博客文章 http://blog.csdn.net/x356982611/article/details/51260841 http://www.cnblogs.com/antonioz ...

  4. diff 命令详解

    [自注:] 1,还有个colordiff命令,用颜色标识不同的地方.需要先安装 2,diff normal模式中 2,5表示从第二行到第五行 3,diff -c 模式中,2,5表示从第二行到第五行 4 ...

  5. LwIP协议栈接口

    协议栈api函数 1.netconn_new      //UDP    TCP struct netconn*netconn_new(enum netconn_type t) 为新连接申请一个连接结 ...

  6. 获取Lambda表达式内表达式的值

    随着Linq的盛行,对于Linq和Lmabda表达式的使用也越来越多,Lambda表达式在.net framework 3.5中提出来,Lambda表达式是一个匿名方法,通常在LINQ中被用来创建委托 ...

  7. mysql数据库到底是什么?!

    MySql是MySql.AB公司开发的,采用客户/服务器模型的开放源码关系型SQL数据库管理系统,它可以在多种操作系统上运行. 客户端/服务器:C/S.需要给不同系统安装不同的软件,是专用的协议,比较 ...

  8. 微信小程序如何套用iconfont

    前言 如果你在开发微信时,没有图标的话,可以到http://www.iconfont.cn/ 官方下使用图标,那么我们去使用一些吧,到官方网址下点击使用~ 下载代码即可使用,看看下载的文件吧. 如图可 ...

  9. Archive required for library “xxx” cannot be read or is not a valid zip file报错解决

    在项目中导入别人的maven项目时报错:Archive required for library “xxx” cannot be read or is not a valid zip file 网上查 ...

  10. C#6.0语言规范(三) 基本概念

    应用程序启动 具有入口点的程序集称为应用程序.运行应用程序时,会创建一个新的应用程序域.应用程序的几个不同实例可以同时存在于同一台机器上,并且每个实例都有自己的应用程序域. 应用程序域通过充当应用程序 ...