佛山营销网站建设费用,融水县建设局网站,漯河网站建设lhwzzz,好公司的网站设计转载自 如何使用jstack分析线程状态背景
记得前段时间#xff0c;同事说他们测试环境的服务器cpu使用率一直处于100%#xff0c;本地又没有什么接口调用#xff0c;为什么会这样#xff1f;cpu使用率居高不下#xff0c;自然是有某些线程一直占用着cpu资源#xff0c;那…转载自 如何使用jstack分析线程状态背景
记得前段时间同事说他们测试环境的服务器cpu使用率一直处于100%本地又没有什么接口调用为什么会这样cpu使用率居高不下自然是有某些线程一直占用着cpu资源那又如何查看占用cpu较高的线程当然一个正常的程序员不会写出上述代码这里只是为了让一个线程占用较高的cpu资源。
top命令
在linux环境下可以通过top命令查看各个进程的cpu使用情况默认按cpu使用率排序1、上图中可以看出pid为23344的java进程占用了较多的cpu资源2、通过top -Hp 23344可以查看该进程下各个线程的cpu使用情况上图中可以看出pid为25077的线程占了较多的cpu资源利用jstack命令可以继续查看该线程当前的堆栈状态。
jstack命令
通过top命令定位到cpu占用率较高的线程之后继续使用jstack pid命令查看当前java进程的堆栈状态jstack命令生成的thread dump信息包含了JVM中所有存活的线程为了分析指定线程必须找出对应线程的调用栈应该如何找
在top命令中已经获取到了占用cpu资源较高的线程pid将该pid转成16进制的值在thread dump中每个线程都有一个nid找到对应的nid即可隔段时间再执行一次stack命令获取thread dump区分两份dump是否有差别在nid0x246c的线程调用栈中发现该线程一直在执行JstackCase类第33行的calculate方法得到这个信息就可以检查对应的代码是否有问题。
通过thread dump分析线程状态
除了上述的分析大多数情况下会基于thead dump分析当前各个线程的运行情况如是否存在死锁、是否存在一个线程长时间持有锁不放等等。
在dump中线程一般存在如下几种状态1、RUNNABLE线程处于执行中2、BLOCKED线程被阻塞3、WAITING线程正在等待
实例1多线程竞争synchronized锁很明显线程1获取到锁处于RUNNABLE状态线程2处于BLOCK状态1、locked 0x000000076bf62208说明线程1对地址为0x000000076bf62208对象进行了加锁2、waiting to lock 0x000000076bf62208 说明线程2在等待地址为0x000000076bf62208对象上的锁3、waiting for monitor entry [0x000000001e21f000]说明线程1是通过synchronized关键字进入了监视器的临界区并处于”Entry Set”队列等待monitor具体实现可以参考深入分析synchronized的JVM实现
实例2通过wait挂起线程
static class Task implements Runnable {Overridepublic void run() {synchronized (lock) {try {lock.wait();//TimeUnit.SECONDS.sleep(100000);} catch (InterruptedException e) {e.printStackTrace();}}}
}dump结果线程1和2都处于WAITING状态1、线程1和2都是先locked 0x000000076bf62500再waiting on 0x000000076bf62500之所以先锁再等同一个对象是因为wait方法需要先通过synchronized获得该地址对象的monitor2、waiting on 0x000000076bf62500说明线程执行了wait方法之后释放了monitor进入到”Wait Set”队列等待其它线程执行地址为0x000000076bf62500对象的notify方法并唤醒自己具体实现可以参考深入分析Object.wait/notify实现机制