背景
本人在刚开始接触企业级开发的时候,就曾经写过一段类似于死循环的代码。然后把这个代码发布到线上,Grafana显示该应用上线后CPU一直接近100%,于是在大佬的帮助下用jstack定位到问题并且解决了,所以总结一下jstack的使用吧。
jstack描述
此命令是为Java进程或核心文件或远程调试服务器打印Java线程的堆栈跟踪。jstack可以同时打印所有线程的Java和本机栈帧。jstack常用于定位线程的死循环、死锁等情况。
场景模拟
1 | package JVM; |
当运行以上的程序,由于出现了死循环,往往表现出来的时候是CPU100%,这个时候我们应该进去服务器,用top命令查找出CPU占用率最高的进程pid。
用top命令发现了CPU占用率最高的pid为1639,这个时候就要用top -H -p 1639去该进程里面查看各个线程的情况,找到线程占用率最高的nid。(由于博主用的是mac电脑,没有top -H命令,所以就不演示这一步了~~~)
可以用jps查出目前正在运行的Java进程,知道1639对应的是JstackDemo这个java进程
然后可以用jstack pid来分析线程的堆栈情况
可以发现nid=0xe03线程出现了等待,初步判断为死循环。(WAITING一般为死循环,BLOCKED一般为死锁),看到是JstackDemo的22行出问题,所以去程序找到对应的行数分析。
最后定位到这里,发现是死循环引起的,根据不同的场景和情况去解决即可。
重点归纳
发现CPU100%的解决思路大致可以分为以下:
- 用top查出CPU占用率高的进程pid
- 用jps大致确定pid是对应线上的哪个进程导致的
- 用top -H -p pid找到该pid下线程占用率最高的线程nid,此时nid是10进制
- 用jstack pid | grep nid查出对应的堆栈情况,这里要注意nid是要转换为16进制
- 根据WAITING或者BLOCKED大致判断是死循环还是死锁,然后回到程序中定位代码并且根据业务场景解决
总结
根据本人在企业开发遇到的一次线上CPU100%的事故,然后引起对Jstack的学习,知道jstack的作用还有对线上问题排查和定位的过程。希望以上分享对Java程序员有所帮助。