jstack分析线程状态

背景

记得前段时间,同事说他们测试环境的服务器cpu使用率一直处于100%,本地又没有什么接口调用,为什么会这样?cpu使用率居高不下,自然是有某些线程一直占用着cpu资源,那又如何查看占用cpu较高的线程?

/**
 *一个线程占用较高的cpu资源
 *
 * Created by haoting.wang on 2017/2/24.
 */
public class JstackCase {


    static ExecutorService executorService = Executors.newFixedThreadPool(5);

    public static void main(String[] args) {

        Task task1 = new Task();
        Task task2 = new Task();
        executorService.execute(task1);
        executorService.execute(task2);
    }


    public static Object lock = new Object();

    static class Task implements Runnable{

        public void run() {

            synchronized (lock){
                calculate();
            }
        }

        public void calculate(){
            long i = 0L;
            while (true){
                i++;
            }
        }
    }
}

top命令

在linux环境下,可以通过top命令查看各个进程的cpu使用情况,默认按cpu使用率排序
image_1b9nf34ns34ldk7mrob4g17o920.png-104kB

1、上图中可以看出pid为18106的java进程占用了较多的cpu资源;
2、通过top -Hp 18106可以查看该进程下各个线程的cpu使用情况;

image_1b9nf7nf38sqs3f1crtr541duo2d.png-96.1kB

上图中可以看出pid为18121的线程占了较多的cpu资源,利用jstack命令可以继续查看该线程当前的堆栈状态。

jstack命令

通过top命令定位到cpu占用率较高的线程之后,继续使用jstack pid命令查看当前java进程的堆栈状态
jstack 18106

![image_1b9nfqthhs2p1a1f10s81olk2vl2q.png-91.7kB](http://static.zybuluo.com/1234567890/eg7krr6agqha8ry9vip2p58q/image_1b9nfqthhs2p1a1f10s81olk2vl2q.png)

在top命令中,已经获取到了占用cpu资源较高的线程pid,将该pid转成16进制的值,在thread dump中每个线程都有一个nid,找到对应的nid即可;隔段时间再执行一次stack命令获取thread dump,区分两份dump是否有差别,在nid=0x246c的线程调用栈中,发现该线程一直在执行JstackCase类第33行的calculate方法,得到这个信息,就可以检查对应的代码是否有问题。

通过thread dump分析线程状态

除了上述的分析,大多数情况下会基于thead dump分析当前各个线程的运行情况,如是否存在死锁、是否存在一个线程长时间持有锁不放等等。

image_1b9ngg3ih7rh199474c1ecm45s3k.png-22.3kB

在dump中,线程一般存在如下几种状态:

  1. RUNNABLE,线程处于执行中

  2. BLOCKED,线程被阻塞

  3. WAITING,线程正在等待

    “Entry Set”中等待的线程状态是 “Waiting for monitor entry”,而在 “Wait Set”中等待的线程状态是 “in Object.wait()。Wait on condition网络瓶颈的征兆”。 
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值