记得前段时间,同事说他们测试环境的服务器cpu使用率一直处于100%,本地又没有什么接口调用,为何会这样?cpu使用率居高不下,天然是有某些线程一直占用着cpu资源,那又如何查看占用cpu较高的线程?java
/** *一个线程占用较高的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++; } } } }
在linux环境下,能够经过top命令查看各个进程的cpu使用状况,默认按cpu使用率排序linux
一、上图中能够看出pid为18106的java进程占用了较多的cpu资源;
二、经过top -Hp 18106能够查看该进程下各个线程的cpu使用状况;服务器
上图中能够看出pid为18121的线程占了较多的cpu资源,利用jstack命令能够继续查看该线程当前的堆栈状态。网络
经过top命令定位到cpu占用率较高的线程以后,继续使用jstack pid命令查看当前java进程的堆栈状态
jstack 18106测试
在top命令中,已经获取到了占用cpu资源较高的线程pid,将该pid转成16进制的值,在thread dump中每一个线程都有一个nid,找到对应的nid便可;隔段时间再执行一次stack命令获取thread dump,区分两份dump是否有差异,在nid=0x246c的线程调用栈中,发现该线程一直在执行JstackCase类第33行的calculate方法,获得这个信息,就能够检查对应的代码是否有问题。spa
除了上述的分析,大多数状况下会基于thead dump分析当前各个线程的运行状况,如是否存在死锁、是否存在一个线程长时间持有锁不放等等。线程
在dump中,线程通常存在以下几种状态:code
RUNNABLE,线程处于执行中排序
BLOCKED,线程被阻塞接口
WAITING,线程正在等待
“Entry Set”中等待的线程状态是 “Waiting for monitor entry”,而在 “Wait Set”中等待的线程状态是 “in Object.wait()。Wait on condition网络瓶颈的征兆”。