博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
如何使用jstack分析线程状态
阅读量:5868 次
发布时间:2019-06-19

本文共 1803 字,大约阅读时间需要 6 分钟。

背景

记得前段时间,同事说他们测试环境的服务器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是否有差别,在nid=0x246c的线程调用栈中,发现该线程一直在执行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,具体实现可以参考;

实例2:通过wait挂起线程
static class Task implements Runnable {    @Override    public 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获得该地址对象的monitor;
2、waiting on <0x000000076bf62500>说明线程执行了wait方法之后,释放了monitor,进入到"Wait Set"队列,等待其它线程执行地址为0x000000076bf62500对象的notify方法,并唤醒自己,具体实现可以参考;

 

转载:http://www.jianshu.com/p/6690f7e92f27

你可能感兴趣的文章
被神话的大数据——从大数据(big data)到深度数据(deep data)思维转变
查看>>
修改校准申请遇到的问题
查看>>
【DL-CV】浅谈GoogLeNet(咕咕net)
查看>>
python大佬养成计划----win下对数据库的操作
查看>>
监控软件zabbix之安装
查看>>
Exchange Server 2016 独立部署/共存部署 (七)—— DAG功能测试
查看>>
对RTMP视频流进行BitmapData.draw()出错的解决办法
查看>>
Linux 进程中 Stop, Park, Freeze【转】
查看>>
Spark修炼之道(基础篇)——Linux大数据开发基础:第九节:Shell编程入门(一)...
查看>>
Duplicate Symbol链接错误的原因总结和解决方法[转]
查看>>
适配器模式
查看>>
建立低权限的ftp帐号
查看>>
htpasswd
查看>>
Android窗口机制(三)Window和WindowManager的创建与Activity
查看>>
Android 编译出错解决
查看>>
Android 打开WIFI并快速获取WIFI的信息
查看>>
【IOS开发】GDataXML解析XML
查看>>
GridView多行多列合并单元格(指定列合并)
查看>>
什么是DDOS攻击?怎么防御?
查看>>
状态模式(State Pattern)
查看>>