服务器CPU居高不下--解决问题历程

基本的概述

在一个服务器的集群上面,服务器的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。

时间: 2024-10-09 04:24:45

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

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

网上搜,东拼西凑,组装了一个可以查Linux服务器CPU使用率.内存使用率.磁盘空间占用率.负载情况的python脚本. 脚本内容如下: # -*- coding:utf-8 -*- - import os, time last_worktime=0 last_idletime=0 def get_cpu(): global last_worktime, last_idletime f=open("/proc/stat","r") line=""

【故障公告】再次出现数据库 CPU 居高不下的问题以及找到了最可能的原因

非常非常抱歉,今天上午的故障又一次给大家带来麻烦了,再次恳请大家的谅解. 在昨天升级阿里云 RDS SQL Server 实例的配置后(详见昨天的博文),万万没有想到,今天上午更高配置的阿里云 RDS 实例依然出现了 CPU 居高不下的问题. 在数据库 CPU 高的情况下,有时对访问速度影响不大,有时巨慢无边,在今天上午的故障期间,我们通过2次主备切换才恢复了正常. 下午,我们我们调整了服务器的部署,用了更多服务器进行混合部署(docker-compose与docker swarm),情况有了明

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

处理器史话 | 服务器CPU市场的战役, AMD.Intel和ARM的厮杀 https://www.eefocus.com/mcu-dsp/377300 说完了个性鲜明的消费类电子,接下来聊一聊通用的“巨无霸”型 CPU——服务器 CPU.服务器 CPU,顾名思义,就是在服务器上使用的 CPU. 众所周知,服务器是网络中的重要设备,要接受少至几人.几十人,或者多至成千上万人的访问,因此,对服务器具有大数据量的快速吞吐.超强的稳定性.长时间运行等严格要求.作为计算机“大脑”的 CPU,是衡量服务器

[转帖]Java性能检测工具-记录一次通过jstack排查Linux服务器CPU占用率很高的实践

Java性能检测工具-记录一次通过jstack排查Linux服务器CPU占用率很高的实践 https://www.jianshu.com/p/d4e31301ba2e 一.问题描述 Linux服务器的配置是4核16G,将war包部署到tomcat后,启动tomcat,发现内存占用率不高,但是CPU一直高达100%:浏览器输入相关url也无法访问该项目,且tomcat的进程一直存在,程序的配置什么的都没问题啊,一头雾水......通过top命令查看服务器的性能状况如下: [[email prote

服务器CPU使用率过高的处理

最近发现公司服务器搭建的网站访问缓慢,服务器输入命令也反应慢,处理步骤如下: 1.通过top命令查看服务器CPU.内存.IO等使用情况 发现CPU基本在80%以上:内存还好,有富余:CPU平均加载率Load Average也是达到40左右 2.通过vmstat.iostat参看相关参数,确认是CPU占用很高,CPU不够用,当时以为服务器CPU被用完了,但是应用不是很多,两CPU是够用的 3.后来慢慢看进程和服务线程以及端口号占用和包发送,(w.procinfo.ps.uptime.netstat

监控HP服务器CPU温度的脚本

监控HP服务器CPU温度的脚本: #!/bin/bash Name=`hostname` IP=`/sbin/ifconfig eth0 | grep "inet addr" | awk -F[:" "]+ '{print $4}'` Date=`date +%m%d%y` Date2=`date +%H:%M` Num=`/usr/sbin/dmidecode | grep -i 'serial number' | head -n 1` CPU1=`/sbin/h

一个让服务器CPU飙升的BUG。找了2天才发现。

昨天升级了站点.发现一升级上去,就发现站点服务器CPU开始占用接近100%.但是数据库服务器变化不大 还原回更新之前的代码.立马CPU降低.一开始已经是增加的缓存机制有了问题,采用数据库读取,放到线上依旧. 接着以为是数据统计有问题,删除掉还是一样.最后的最后,通过看到工作线程,发现登录请求也蛮多的. 然后这个登录代码更新到旧版本.就OK了.这次版本对登录进行了重构.直接上代码 错误代码中 登录后直接是使用了user.BbbID,造成了500错误.IIS对这个500错误也会有CPU损耗.于是就飙

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

一.背景 前段时间服务器出了点问题,加上学业愈来愈紧张,写博文分享的时间越来越少.虽然不是第一次在博客园上写经验,但是近期分享的博文得到了不少的朋友支持和指正,在这里内心非常感激和开心.希望以后能认真用好时间,把一些有用的经验分享给需要的人,当然本科阶段的我还有许多不懂的,如果在文章中有错误,希望大家多多指正,必虚心受教. 今天要分享的是使用c#获取服务器CPU.RAM.TCP.磁盘使用情况.前段时间,做了一个几十人的并发测试,服务器宕机了,后来上控制管理台检查测试时间段里服务器各项数据,可惜没

4核服务器cpu使用率10%负载飙到23.5故障排查

遇到一个故障,一台4核服务器cpu利用率是10%负载却飙到23,先看下问题现场,截图如下:...... 浏览全部请点击运维网咖社地址:4核服务器cpu使用率10%负载飙到23.5故障排查