java线上故障排查技巧-cpu

    线上故障主要包括CPU,磁盘,内尺寸以及网络问题,大多数故障可能会包含多个层面,所以排查时尽量四个方面依次排查一遍。

CPU

问题出现原因:业务代码(死循环),频繁GC以及上下文切换,数据库排序计算等等。

首先java应用排查:

1.使用jstack分析CPU问题

首先我们用jps找到对应java进程的pid,top pid,看一下哪一个线程的占用比较高,然后top -H -p 线程pid ,找到CPU使用率较高的线程。

java线上故障排查技巧-cpu

可以看到线程41964线程的cpu的占用率较高,然后我们将41964转换为16进制的 printf '%x\n' 41964 得到线程nid:a3ec

接下来在jstack中找到响应给的堆栈信息 :jstack  41964 | grep 'a3ec' -C 10

java线上故障排查技巧-cpu

可以看到该线程为runnable状态,在做mysql数据库读取操作,线程属于c3p0线程池。

如果我们想查询具体某个线程在做是什么,可以:jstack 41964 | grep '线程名称' -A 20

拓展:-A 20代表往下20行 -B代表往上20行 -C代表上下20行

 

2.频繁GC

首先确定GC是否频繁

jstat -gc 进程pid 1000 来对GC分带变化情况进行观察,1000代表采样间隔(ms)

S0C/S1C,S0U/S1U,EC/EU,OC/OU,MC/MU分别代表连能改个Survivor区,Eden区,老年代,元数据区的容量和使用量,

YGC/YGCT,FGC/FGCT,GCT则代表  YoungGc.FullGc的耗时和次数以及总耗时。

java线上故障排查技巧-cpu

Java 堆分为新生代和老年代,新生代一般划分为三块区域,Eden + From Survivor + To Survivor,Eden 和 Survivor 的内存比为8:1,每次只使用一个Eden 和一个 Survivor 区域,另一个Survivor 用于复制收集算法回收内存。

java线上故障排查技巧-cpu

对象一般尽量分配到新生代中,而对于大对象(长字符串和大数组)直接分配在老年代中,同时“年龄”长的的对象会从新生代自动晋升到老年代中。

Java 方法区称为永久代,只有 HotSpot 虚拟机才存在永久代。

首先想eden区申请分配空间,如果空间够,就直接进行分配,否则进行一次Minor GC。minor GC 首先会对Eden区的对象进行标记,标记出来存活的对象。然后把存活的对象copy到From空间。如果From空间足够,则回收eden区可回收的对象。如果from内存空间不够,则把From空间存活的对象复制到To区,如果TO区的内存空间也不够的话,则把To区存活的对象复制到老年代。如果老年代空间也不够(或者达到触发老年年垃圾回收条件的话)则触发一次full GC。

使用jinfo 41426获取java进程jvm参数配置。

gc日志怎样 从此查看:GC日志学习

3.上下文切换

命令:vmstat  1  

cs代表上下文切换的次数