使用jstack排查线程问题
以一个例子来演示排查服务器cpu占用率过高的问题。
准备
将下面的代码文件上传到服务器上,然后使用javac编译,并使用java命令将程序跑起来。
public class JStackCase {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(5);
executor.submit(new Task());
executor.submit(new Task());
}
}
class Task implements Runnable {
@Override
public void run() {
synchronized (this) {
calculate();
}
}
public void calculate() {
int i = 0;
while (true) {
i++;
}
}
}
显然,这段程序会导致CPU占用率较高。接下来,我们进行问题排查。
1.定位进程
使用top命令查看cpu占用情况,默认按cpu使用率从高到低排序。我们发现pid为6624的进程占用了70%的cpu。
[root@localhost bin]# top
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
6624 root 20 0 2249296 18380 10704 S 70.0 1.8 6:00.17 java
6723 root 20 0 157716 2112 1472 R 5.0 0.2 0:00.03 top
1 root 20 0 193724 3608 1972 S 0.0 0.4 0:07.07 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:00.01 kthreadd
3 root 20 0 0 0 0 S 0.0 0.0 0:13.54 ksoftirqd/0
5 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/0:0H
7 root rt 0 0 0 0 S 0.0 0.0 0:00.40 migration/0
8 root 20 0 0 0 0 S 0.0 0.0 0:00.00 rcu_bh
9 root 20 0 0 0 0 S 0.0 0.0 0:04.98 rcu_sched
10 root rt 0 0 0 0 S 0.0 0.0 0:04.42 watchdog/0
12 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kdevtmpfs
13 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 netns
14 root 20 0 0 0 0 S 0.0 0.0 0:00.00 khungtaskd
15 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 writeback
16 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kintegrityd
17 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 bioset
18 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kblockd
19 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 md
25 root 20 0 0 0 0 S 0.0 0.0 0:10.50 kswapd0
26 root 25 5 0 0 0 S 0.0 0.0 0:00.00 ksmd
27 root 39 19 0 0 0 S 0.0 0.0 0:00.21 khugepaged
28 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 crypto
36 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kthrotld
38 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kmpath_rdacd
39 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kpsmoused
2.定位线程
查看pid为6624的进程下的线程cpu占用情况。发现6634和6635线程几乎占用了大部分的cpu。
[root@localhost bin]# top -Hp 6624
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
6634 root 20 0 2249296 16532 8852 R 49.8 1.7 6:34.75 java
6635 root 20 0 2249296 16532 8852 R 49.5 1.7 6:34.69 java
6624 root 20 0 2249296 16532 8852 S 0.0 1.7 0:00.04 java
6625 root 20 0 2249296 16532 8852 S 0.0 1.7 0:00.09 java
6626 root 20 0 2249296 16532 8852 S 0.0 1.7 0:00.01 java
6627 root 20 0 2249296 16532 8852 S 0.0 1.7 0:00.00 java
6628 root 20 0 2249296 16532 8852 S 0.0 1.7 0:00.00 java
6629 root 20 0 2249296 16532 8852 S 0.0 1.7 0:00.00 java
6630 root 20 0 2249296 16532 8852 S 0.0 1.7 0:00.00 java
6631 root 20 0 2249296 16532 8852 S 0.0 1.7 0:00.00 java
6632 root 20 0 2249296 16532 8852 S 0.0 1.7 0:00.00 java
6633 root 20 0 2249296 16532 8852 S 0.0 1.7 0:00.54 java
3.定位代码
接下来jstack就要上场了。可以使用jstack -l [pid]查看线程的堆栈信息。
jstack -l [pid] //进程id
当然,我们可以过滤我们只关注的线程的转储信息。
将线程pid转为16进制
因为thread id在栈信息中是以十六进制的形式显示的,所以可以使用printf "%x \n" [pid]命令将线程pid转为16进制。
[root@localhost bin]# printf "%x \n" 6634
19ea
[root@localhost bin]# printf "%x \n" 6635
19eb
过滤19ea线程的堆栈信息,使用jstack -l <pid> | grep <thread-hex-id> -A 10。-A 10 参数用来指定显示行数,否则只会显示一行信息。
[root@localhost bin]# jstack -l 6624 | grep 19ea -A 10
"pool-1-thread-1" #8 prio=5 os_prio=0 tid=0x00007f22e00e4800 nid=0x19ea runnable [0x00007f22d0729000]
java.lang.Thread.State: RUNNABLE
at Task.calculate(JStackCase.java:26)
at Task.run(JStackCase.java:19)
- locked <0x00000000f0a60ff8> (a Task)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:748)
可以看到定位到代码JstackCase类中第26行。接下来在分析对应的代码即可。
通常,在线上环境远比这复杂,所以需要多次获取线程堆栈信息,进行对比综合分析。所以,仅仅单独分析一个文件是可能并没有太大意义的。
当然我们也可以使用其它的工具来排查问题,比如系统自带的perf,Alibaba开源的工具Arthas等。
使用jstack排查线程问题的更多相关文章
- jstack(查看线程)、jmap(查看内存)和jstat(性能分析)
公司内部同事分享的一篇文章 周末看到一个用jstack查看死锁的例子.昨天晚上总结了一下jstack(查看线程).jmap(查看内存)和jstat(性能分析)命令.供大家参考 1.Jstack 1.1 ...
- jstack(查看线程)、jmap(查看内存)和jstat(性能分析)命令
jstack(查看线程).jmap(查看内存)和jstat(性能分析)命令 公司内部同事分享的一篇文章 周末看到一个用jstack查看死锁的例子.昨天晚上总结了一下jstack(查看线程).jma ...
- 命令:jstack(查看线程)、jmap(查看内存)和jstat(性能分析)命令
命令:jstack(查看线程).jmap(查看内存)和jstat(性能分析)命令 这些命令 必须 在 linux jdk bin 路径 下执行 eq: ./jstack 10303 即可 如果想把 ...
- 转: 如何使用jstack分析线程状态
这个讲的好系列: 如何使用jstack分析线程状态 转:http://www.jianshu.com/p/6690f7e92f27 背景 记得前段时间,同事说他们测试环境的服务器cpu使用率一直处于 ...
- jstack分析线程死锁
一.介绍 jstack是java虚拟机自带的一种堆栈跟踪工具.jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息,如果是在64位机器上,需要指定选项&qu ...
- jstack和线程dump分析
转自:http://jameswxx.iteye.com/blog/1041173 一:jstack jstack命令的语法格式: jstack <pid>.可以用jps查看java进程 ...
- java jstack dump 线程 介绍 解释
最近抽时间把JVM运行过程中产生的一些线程进行了整理,主要是围绕着我们系统jstack生成的文件为参照依据. 前段时间因为系统代码问题,造成性能到了天花板,于是就dump了一份stack出来进行分析 ...
- Java内存泄漏分析系列之一:使用jstack定位线程堆栈信息
原文地址:http://www.javatang.com 前一段时间上线的系统升级之后,出现了严重的高CPU的问题,于是开始了一系列的优化处理之中,现在将这个过程做成一个系列的文章. 基本概念 在对J ...
- 使用 jstack 查询线程死锁错误日志 定位问题
定位问题 (1) 首先 找到相应的进程 使用 ps -ef | grep 'com.sankuai.qcs.regulation.dispatch' 找到进程的ID;==>21980 (2) t ...
随机推荐
- [luogu]P1168 中位数[堆]
[luogu]P1168 中位数 题目描述 给出一个长度为N的非负整数序列A[i],对于所有1 ≤ k ≤ (N + 1) / 2,输出A[1], A[3], …, A[2k - 1]的中位数.即前1 ...
- php linux环境安装ftp扩展
1.进入PHP安装源码包,找到ext下的ftp,进入 cd /home/local/php-5.6.25/ext/ftp 2./usr/local/php/bin/phpize 3../configu ...
- ASP汉字转拼音函数的方法
<% 'ASP汉字转拼音函数 Set d = CreateObject("Scripting.Dictionary") d.add "a",-20319 ...
- Linux 系统下文件夹与文件的读写可执行权限问题
linux是一个多用户操作系统,linux对文件系统内的所有文件,实行了严格的权限划分管理.防止没有权限的用户访问某个文件.linux文件或目录的权限分为 读.写.可执行三种权限.文件访问的用户类别分 ...
- Solr核心(内核)
Solr核心(内核) Solr核心(Core)是Lucene索引的运行实例,包含使用它所需的所有Solr配置文件.我们需要创建一个Solr Core来执行索引和分析等操作. Solr应用程序可以包 ...
- RequestBody 请求格式
@RequestMapping("/CreateComment")@ResponseBodypublic String createQuestionComments(@Reques ...
- applicationContext.xml无错有红叉,Error occured processing XML 'Provider org.apache.xerces.parsers.解决方案
applicationContext.xml无错有红叉,网上讲的取消xml验证的方法没用... 甚至我的myeclipse10连windows-->perferences-->myecli ...
- 测开之路七十六:linux变量和环境变量
变量 赋值 variable=0,访问 $var或${var} 参数 $n 用``引住的会先执行(~键) 位置参数 环境变量/etc/profile:全局的环境变量 . bash_profile:用户 ...
- 大数据学习笔记之Zookeeper(二):Zookeeper实战篇(一)
文章目录 2.1 本地模式安装部署 2.2 配置参数解读 2.1 本地模式安装部署 1)安装前准备: (1)安装jdk (2)通过filezilla工具拷贝zookeeper到到linux系统下 (3 ...
- SQL的一对多,多对一,一对一,多对多
1.一对多:比如说一个班级有很多学生,可是这个班级只有一个班主任.在这个班级中随便找一个人,就会知道他们的班主任是谁:知道了这个班主任就会知道有哪几个学生.这里班主任和学生的关系就是一对多. 2.多对 ...