以一个例子来演示排查服务器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排查线程问题的更多相关文章

  1. jstack(查看线程)、jmap(查看内存)和jstat(性能分析)

    公司内部同事分享的一篇文章 周末看到一个用jstack查看死锁的例子.昨天晚上总结了一下jstack(查看线程).jmap(查看内存)和jstat(性能分析)命令.供大家参考 1.Jstack 1.1 ...

  2. jstack(查看线程)、jmap(查看内存)和jstat(性能分析)命令

    jstack(查看线程).jmap(查看内存)和jstat(性能分析)命令   公司内部同事分享的一篇文章 周末看到一个用jstack查看死锁的例子.昨天晚上总结了一下jstack(查看线程).jma ...

  3. 命令:jstack(查看线程)、jmap(查看内存)和jstat(性能分析)命令

    命令:jstack(查看线程).jmap(查看内存)和jstat(性能分析)命令 这些命令 必须 在 linux jdk bin 路径 下执行 eq: ./jstack 10303 即可  如果想把 ...

  4. 转: 如何使用jstack分析线程状态

    这个讲的好系列:  如何使用jstack分析线程状态 转:http://www.jianshu.com/p/6690f7e92f27 背景 记得前段时间,同事说他们测试环境的服务器cpu使用率一直处于 ...

  5. jstack分析线程死锁

    一.介绍 jstack是java虚拟机自带的一种堆栈跟踪工具.jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息,如果是在64位机器上,需要指定选项&qu ...

  6. jstack和线程dump分析

    转自:http://jameswxx.iteye.com/blog/1041173 一:jstack jstack命令的语法格式: jstack  <pid>.可以用jps查看java进程 ...

  7. java jstack dump 线程 介绍 解释

    最近抽时间把JVM运行过程中产生的一些线程进行了整理,主要是围绕着我们系统jstack生成的文件为参照依据.  前段时间因为系统代码问题,造成性能到了天花板,于是就dump了一份stack出来进行分析 ...

  8. Java内存泄漏分析系列之一:使用jstack定位线程堆栈信息

    原文地址:http://www.javatang.com 前一段时间上线的系统升级之后,出现了严重的高CPU的问题,于是开始了一系列的优化处理之中,现在将这个过程做成一个系列的文章. 基本概念 在对J ...

  9. 使用 jstack 查询线程死锁错误日志 定位问题

    定位问题 (1) 首先 找到相应的进程 使用 ps -ef | grep 'com.sankuai.qcs.regulation.dispatch' 找到进程的ID;==>21980 (2) t ...

随机推荐

  1. Hadoop学习之路(二)HDFS基础

    1.HDFS前言 HDFS:Hadoop Distributed File System,Hadoop分布式文件系统,主要用来解决海量数据的存储问题. 设计思想 分散均匀存储 dfs.blocksiz ...

  2. What code you will get when you create a wcf library

    创建wcf服务库的时候,系统自动生成的代码 // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“IService1”. [ServiceContract] publ ...

  3. Python3.5自带venv创建虚拟环境

    为每个程序单独创建虚拟环境可以保证程序只能访问虚拟环境中的包,保持全局解释器的干净整洁,使其只作为创建(更多)虚拟环境的源. windows下创建虚拟环境 Python3.5自带venv,只需执行py ...

  4. tr:hover变色的问题

    做表格隔行变色(高亮显示),可以通过设置css中的 tr:hover伪类属性达到效果, 但是,会出一点小问题.td的背景色会覆盖tr的背景色, 在tr:hover下边加上一句:tr:hover td{ ...

  5. 【转】PyQt5系列教程(七)控件

    PyQt5系列教程(七)控件   软硬件环境 Windows 10 Python 3.4.2 PyQt 5.5.1 PyCharm 5.0.4 前言 控件是PyQt应用程序的基石.PyQt5自带很多不 ...

  6. CentOS7 - 安装 VirtualBox

    参考资料 最新的可用安装包可以从这里下载 VirtualBox 是 x86 硬件虚拟化产品,功能上与 VMware Server.KVM.及 Xen 类似,但是 VirtualBox 不修改 Linu ...

  7. HTML-字符实体,平方米(㎡)m²

    转载自:https://blog.csdn.net/hangGe0111/article/details/80983250

  8. vue分页练习

    <!doctype html> <html> <head> <meta charset="UTF-8"> <title> ...

  9. 怎么查看keras 或者 tensorflow 正在使用的GPU

    查看keras认得到的GPU from keras import backend as K K.tensorflow_backend._get_available_gpus() Out[28]: [' ...

  10. java--反射原理及操作

    1.反射原理 反射具体操作 15.反射的原理(********理解********) * 应用在一些通用性比较高的代码 中 * 后面学到的框架,大多数都是使用反射来实现的 * 在框架开发中,都是基于配 ...