生产问题排查之---cpu飙升

什么是线程堆栈

Java线程堆栈是虚拟机中线程(包括锁)状态的一个瞬间快照,即

系统在某个时刻所有线程的运行状态。

包括每一个线程的调用堆栈,锁的持有情况等信息,从线程堆栈中可以得到以下信息:

  1. 线程的名字,ID,线程的数量等;

  2. 线程的运行状态,锁的状态(锁被那个线程持有,哪个线程在等待锁等);

  3. 函数间的调用关系,包括完整类名,所执行的方法,源代码的行数等;

可以通过Jstack获取应用运行时的线程堆栈,可以通过如下方式获取线程堆栈:

jstack pid>>jstack.log

对于Java应用而言,以下常见的几个性能问题都可以从线程堆栈入手定位:

  • 系统挂起无响应

  • 系统CPU较高

  • 系统运行的响应时间长

  • 线程死锁等

cpu飙升的原因都有哪些?

1、代码中存在死循环

public String loop() {
    boolean b = true;
    while (b) {
    }
    return "123";
}

2、高并发的时候,所有线程都处在运行状态,消耗CPU资源。比如定时任务跑批量,比如外部请求大批量访问等等。建议,接口比较耗时的操作不要写成同步。

3、系统发生了频繁的 Full GC(jstat -gcutil pid)来查看各区gc使用率,特别是老年代fullgc指的是老年代的gc,如果老年代的内存使用率很高,会造成频繁的fullgc。

线程的运行状态

想知道线程是在卖力工作还是偷懒休息,这就需要关注线程的运行状态,常用到的几个线程状态有:RUNNABLE,Running,BLOCKED,WAITING,TIMED_WAITING。

RUNNABLE

Runnable:当调用thread.start()后,线程变成为Runnable状态。只要得到CPU,就可以执行;
Running:线程正在执行;

Running状态代表线程正处于运行状态。一般情况下处于运行状态线程是会消耗CPU的。

但不是所有的RUNNABLE都会消耗CPU,比如线程进行网络IO时,这时线程状态是挂起的,但由于挂起发生在本地代码,虚拟机并不感知,所以不会像显示调用Java的sleep()或者wait()等方法进入WAITING状态,只有等数据到来时才消耗一点CPU.

WATING

执行thread.join()或在锁对象调用obj.wait()等情况就会进该状态,表明线程正处于等待某个资源或条件发生来唤醒自己;

TIMED_WAITING

执行Thread.sleep(long)、thread.join(long)或obj.wait(long)等就会进该状态,与Waiting的区别在于Timed_Waiting的等待有时间限制;

这两种状态表示线程被挂起,等待被唤醒,当设置超时时间时状态为TIMED_WAITING,如果是未设置超时时间,这时的状态为WATING,必须等待lock.notify()或lock.notifyAll()或接收到interrupt信号才能退出等待状态,TIMED_WAITING/WATING下还需要关注下面几个线程状态:

  • waiting on condition:说明线程等待另一个条件的发生,来把自己唤醒;

  • on object monitor: 说明该线程正在执行obj.wait()方法,放弃了 Monitor,进入 “Wait Set”队列;

BLOCKED

如果进入同步方法或同步代码块,没有获取到锁,则会进入该状态;

此时的线程处于阻塞状态,一般是在等待进入一个临界区“waiting for monitor entry”,这种状态是需要重点关注的

哪些线程状态占用CPU?

处于TIMED_WAITING、WATING、BLOCKED状态的线程是不消耗CPU的,而处于Running状态的线程要结合当前线程代码的性质判断是否消耗CPU

  • 纯java运算代码,并且未被挂起,是消耗CPU的;

  • 网络IO操作,在等待数据时是不消耗CPU的;

对于jstack日志,我们要着重关注如下关键信息
Deadlock:表示有死锁
Waiting on condition:等待某个资源或条件发生来唤醒自己。具体需要结合jstacktrace来分析,比如线程正在sleep,网络读写繁忙而等待
Blocked:阻塞 Waiting on monitor entry:在等待获取锁
in Object.wait():获取锁后又执行obj.wait()放弃锁 

参考


深入理解jstack日志

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值