平时碰到系统CPU飙高和频繁GC,你会怎么排查

  处理过线上问题的同学基本上都会遇到系统突然运行缓慢,CPU 100%,以及Full GC次数过多的问题。当然,这些问题的最终导致的直观现象就是系统运行缓慢,并且有大量的报警。本文主要针对系统运行缓慢这一问题,提供该问题的排查思路,从而定位出问题的代码点,进而提供解决该问题的思路。

  对于线上系统突然产生的运行缓慢问题,如果该问题导致线上系统不可用,那么首先需要做的就是,导出jstack和内存信息,然后重启系统,尽快保证系统的可用性。这种情况可能的原因主要有两种:

  代码中某个位置读取数据量较大,导致系统内存耗尽,从而导致Full GC次数过多,系统缓慢;

  代码中有比较耗CPU的操作,导致CPU过高,系统运行缓慢;

  相对来说,这是出现频率最高的两种线上问题,而且它们会直接导致系统不可用。另外有几种情况也会导致某个功能运行缓慢,但是不至于导致系统不可用:

  代码某个位置有阻塞性的操作,导致该功能调用整体比较耗时,但出现是比较随机的;

  某个线程由于某种原因而进入WAITING状态,此时该功能整体不可用,但是无法复现;

  由于锁使用不当,导致多个线程进入死锁状态,从而导致系统整体比较缓慢。

  对于这三种情况,通过查看CPU和系统内存情况是无法查看出具体问题的,因为它们相对来说都是具有一定阻塞性操作,CPU和系统内存使用情况都不高,但是功能却很慢。下面我们就通过查看系统日志来一步一步甄别上述几种问题。

  1. Full GC次数过多

  相对来说,这种情况是最容易出现的,尤其是新功能上线时。对于Full GC较多的情况,其主要有如下两个特征:

  线上多个线程的CPU都超过了100%,通过jstack命令可以看到这些线程主要是垃圾回收线程

  通过jstat命令监控GC情况,可以看到Full GC次数非常多,并且次数在不断增加。

  首先我们可以使用top命令查看系统CPU的占用情况,如下是系统CPU较高的一个示例:

  top - 08:31:10 up 30 min, 0 users, load average: 0.73, 0.58, 0.34

  KiB Mem: 2046460 total, 1923864 used, 122596 free, 14388 buffers

  KiB Swap: 1048572 total, 0 used, 1048572 free. 1192352 cached Mem

  PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND

  9 root 20 0 2557160 288976 15812 S 98.0 14.1 0:42.60 java

  可以看到,有一个Java程序此时CPU占用量达到了98.8%,此时我们可以复制该进程id9,并且使用如下命令查看呢该进程的各个线程运行情况:

  top -Hp 9

  该进程下的各个线程运行情况如下:

  top - 08:31:16 up 30 min, 0 users, load average: 0.75, 0.59, 0.35

  Threads: 11 total, 1 running, 10 sleeping, 0 stopped, 0 zombie

  %Cpu(s): 3.5 us, 0.6 sy, 0.0 ni, 95.9 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st

  KiB Mem: 2046460 total, 1924856 used, 121604 free, 14396 buffers

  KiB Swap: 1048572 total, 0 used, 1048572 free. 1192532 cached Mem

  PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND

  10 root 20 0 2557160 289824 15872 R 79.3 14.2 0:41.49 java

  11 root 20 0 2557160 289824 15872 S 13.2 14.2 0:06.78 java

  可以看到,在进程为9的Java程序中各个线程的CPU占用情况,接下来我们可以通过jstack命令查看线程id为10的线程为什么耗费CPU最高。需要注意的是,在jsatck命令展示的结果中,线程id都转换成了十六进制形式。可以用如下命令查看转换结果,也可以找一个科学计算器进行转换:

  [email protected]:/# printf "%x\n" 10

  a

  这里打印结果说明该线程在jstack中的展现形式为0xa,通过jstack命令我们可以看到如下信息:

  "main" #1 prio=5 os_prio=0 tid=0x00007f8718009800 nid=0xb runnable [0x00007f871fe41000]

  java.lang.Thread.State: RUNNABLE

  at com.aibaobei.chapter2.eg2.UserDemo.main(UserDemo.java:9)

  "VM Thread" os_prio=0 tid=0x00007f871806e000 nid=0xa runnable

  这里的VM Thread一行的最后显示nid=0xa,这里nid的意思就是操作系统线程id的意思。而VM Thread指的就是垃圾回收的线程。这里我们基本上可以确定,当前系统缓慢的原因主要是垃圾回收过于频繁,导致GC停顿时间较长。我们通过如下命令可以查看GC的情况:

  [email protected]:/# jstat -gcutil 9 1000 10

  S0 S1 E O M CCS YGC YGCT FGC FGCT GCT

  0.00 0.00 0.00 75.07 59.09 59.60 3259 0.919 6517 7.715 8.635

  0.00 0.00 0.00 0.08 59.09 59.60 3306 0.930 6611 7.822 8.752

  0.00 0.00 0.00 0.08 59.09 59.60 3351 0.943 6701 7.924 8.867

  0.00 0.00 0.00 0.08 59.09 59.60 3397 0.955 6793 8.029 8.984

  可以看到,这里FGC指的是Full GC数量,这里高达6793,而且还在不断增长。从而进一步证实了是由于内存溢出导致的系统缓慢。那么这里确认了内存溢出,但是如何查看你是哪些对象导致的内存溢出呢,这个可以dump出内存日志,然后通过eclipse的mat工具进行查看

  经过mat工具分析之后,我们基本上就能确定内存中主要是哪个对象比较消耗内存,然后找到该对象的创建位置,进行处理即可。这里的主要是PrintStream最多,但是我们也可以看到,其内存消耗量只有12.2%。也就是说,其还不足以导致大量的Full GC,此时我们需要考虑另外一种情况,就是代码或者第三方依赖的包中有显示的System.gc()调用。这种情况我们查看dump内存得到的文件即可判断,因为其会打印GC原因:

  [Full GC (System.gc()) [Tenured: 262546K>262546K(349568K), 0.0014879 secs] 262546K->262546K(506816K), [Metaspace: 3109K->3109K(1056768K)], 0.0015151 secs]

  [Times: user=0.00 sys=0.00, real=0.01 secs

  [GC (Allocation Failure) [DefNew: 2795K->0K(157248K), 0.0001504 secs][Tenured: 262546K->402K(349568K), 0.0012949 secs] 265342K->402K(506816K),

  [Metaspace: 3109K->3109K(1056768K)], 0.0014699 secs] [Times: user=0.00

  郑州试管婴儿哪家医院好:http://mobile.changhong120.com/

  郑州能做试管婴儿医院:http://mobile.changhong120.com/

  郑州妇科:http://mobile.zzyyrl.com/

原文地址:https://www.cnblogs.com/wode1/p/CPU.html

时间: 2024-10-09 13:04:59

平时碰到系统CPU飙高和频繁GC,你会怎么排查的相关文章

STORM在线业务实践-集群空闲CPU飙高问题排查

源:http://daiwa.ninja/index.php/2015/07/18/storm-cpu-overload/ 2015-07-18AUTHORDAIWA STORM在线业务实践-集群空闲CPU飙高问题排查有2条评论 STORM在线业务实践-集群空闲CPU飙高问题排查 最近将公司的在线业务迁移到Storm集群上,上线后遇到低峰期CPU耗费严重的情况.在解决问题的过程中深入了解了storm的内部实现原理,并且解决了一个storm0.9-0.10版本一直存在的严重bug,目前代码已经合并

java进程CPU飙高

因为这段时间一直在弄监控,但是工作还是在进行中 因为机器不多,所以今天早上巡检了一下,看到一台生产机器上的CPU飙高 top 然后就请出了大神工具JVM 具体JVM的介绍看:http://www.cnblogs.com/smail-bao/p/6027756.html CPU飙高的话,我们就是用jstack的工具 首先我们使用top查出来是哪个进程导致的CPU飙高 这里我们看到是PID号为11506的进程 这个进程对应的项目是哪个(为了后面可以把错误的定位发给相关的开发人员看),使用ps -au

mongoDB cpu飙高问题

问题描述: 最近几天生产环境上的mongodb一直在报警,cpu飙高,其他如内存.iops.连接数.磁盘操作等都正常.通过定位业务,发现是由于mongodb的表其中一个查询未建立索引导致,110多W的数据,每秒经历的查询10次左右.但是未建立索引导致数据查询走全表扫描,从而致使导致cpu飙高. 解决方式:db.preservationlog.createIndex({eid:1}) ; 为preservationlog表的eid字段创建索引,问题得以解决. cpu曲线图 mongodb所在服务器

STORM在线业务实践-集群空闲CPU飙高问题排查(转)

最近将公司的在线业务迁移到Storm集群上,上线后遇到低峰期CPU耗费严重的情况.在解决问题的过程中深入了解了storm的内部实现原理,并且解决了一个storm0.9-0.10版本一直存在的严重bug,目前代码已经合并到了storm新版本中,在这篇文章里会介绍这个问题出现的场景.分析思路.解决的方式和一些个人的收获. 背景 首先简单介绍一下Storm,熟悉的同学可以直接跳过这段. Storm是Twitter开源的一个大数据处理框架,专注于流式数据的处理.Storm通过创建拓扑结构(Topolog

电脑公司win10系统cpu占用高怎么办| win10cpu占用率高解决办法

相信很多用户都安装了电脑公司win10纯净版系统了,因为win10系统对于硬件的要求并不是很高,硬件要求低了,但是为什么win10系统总是会遇到CPU占用率的问题呢?win10系统CPU占用率高怎么解决呢? 电脑公司win10系统CPU占用率高解决步骤: 1.按快捷键"win+R"快捷键,打开"运行"界面,输入"regedit"代码,如图1所示 2.在"注册表编辑器"界面中,依次展开"HKEY_LOCAL_MACHI

oracle造成系统CPU过高的检查sql

1. 根据占用CPU高的进程号来查询这个进程执行的SQL语句: CPU过高的进程号: #首先找到CPU过高的进程号 # top -bn1 是静态找到占用最高的进程 [[email protected] ~]# top -bn1 | awk '{print $1}' | grep -A2 PID SQL语句: SELECT sql_text FROM V$sqltext a WHERE (a.hash_value, a.address) IN (SELECT DECODE(sql_hash_val

几个常用的内存、CPU飙高 分析工具

Process Hacker.Windbg.vs2017 调试托管内存.Microsoft.Samples.Debugging.ants memory profiler.ants performance profiler 有时间详细介绍这几个工具怎么玩,不过这几个工具只是辅助分析飙高原因,都很难直接定位,需要经验......

JVM 线上故障排查基本操作--CPU飙高

JVM 线上故障排查基本操作 CPU 飚高 线上 CPU 飚高问题大家应该都遇到过,那么如何定位问题呢? 思路:首先找到 CPU 飚高的那个 Java 进程,因为你的服务器会有多个 JVM 进程.然后找到那个进程中的 “问题线程”,最后根据线程堆栈信息找到问题代码.最后对代码进行排查. 如何操作呢? 通过 top 命令找到 CPU 消耗最高的进程,并记住进程 ID. 再次通过 top -Hp [进程 ID] 找到 CPU 消耗最高的线程 ID,并记住线程 ID. 通过 JDK 提供的 jstac

checkpoint防火墙CPU飙高报警

前些天报警系统频繁报出checkpoint防火墙CPU0,CPU1使用率高达95%.登陆checkpoint命令行 expert模式使用"top"命令可以看到一个"monitored"的进程很占用CPU 查了一下相关文档主要是/var/log/db/var/log/下的db文件高达700多M 官方提供的处理方法如下: ===========================================================================