1. 经过top和jstack确定哪些线程耗尽了CPU
背景
有时,线上集群load会突然飙升,无法响应正常请求。
那么引起load飙升的线程究竟在做什么?哪些线程霸占了CPU?可以通过top和jstack命令进行定位。
2. 定位步骤
1. 使用终端1进入目标机器,执行top命令,默认是进程视图,其中PID是进程号,截图如下:
在这里,我们只能看到java进程占用CPU达到115%,那么究竟是那些线程非常耗CPU呢?
2. 由于我们要看到线程,在终端1,按下“H”键或者“shift+h”,top视图会切换到线程视图,其中PID是线程号,截图如下:
可以发现红框内的线程的CPU使用率非常高,占用CPU时间达到1秒左右,显然不正常,但是这些线程在做什么?
3.
打开终端2,使用jstack命令输出这一时刻的线程栈,保存到文件,命名为jstack.log。注意:输出线程栈和保存top命令快照尽量同时进行。
4. 由于jstack.log文件记录的线程ID是16进制,需要将top命令展示的线程号转换为16进制,以15100为例,在linux下输入命令:printf 0x%x 15100,得到15100的十六进制为0x3afc
5. 在jstack.log中搜索0x3afc关键字,可以清晰看到该线程在做刷新地址列表,如下图:
3. 总结
以前碰到集群load飙升时,有时会束手无策,不知从何查起。以后再发生类似问题时,可以使用这个方法,看下究竟是那些线程在长时间占用CPU,尽快定位问题和解决问题。
2. openjdk中没有jstack怎么办
首先在cmd下输入
jps -l -m
查询pid
例子:
C:\herong>\Progra~1\java\jdk1.8.0\bin\jps -l -m
3296 LongSleep
2224 sun.tools.jps.Jps -l -m
C:\herong>\Progra~1\java\jdk1.8.0\bin\jstack 3296
3. python中有没有像java中的jstack命令
没有像jstack那么方便直接用的东西,一般来说有几个方案:
IDE: 用诸如 PyCharm, Eclpise with Pydev 的工具调试,觉得挂起的时候暂停并检查各个调用栈。
GDB: 优点是可以调试到native extension,缺点也很明显,需要在编译Python的时候加上Debug Symbols,默认这个是没有的。简单的说就是功能强大但是配得麻烦。
pdb:适合下断点...
pudb: 改下代码,在程序入口import pudb; pudb.set_interrupt_handler(),在运行的时候就可以Ctrl-C进入到交互式调试环境,易用性还好吧。
撸一个singal handler用于打印所有栈信息,参考 celery 实现的 install_cry_handler,或者看看 signalhandler,这个在 Python 3.3 自带了。
4. 如何使用jstack分析线程状态
1、上图中可以看出pid为23344的java进程占用了较多的cpu资源; 2、通过top -Hp 23344可以查看该进程下各个线程的cpu使用情况; 上图中可以看出pid为25077的线程占了较多的cpu资源,利用jstack命令可以继续查看该线程当前的堆栈状态。 jstack命令...
5. 通过top和jstack确定哪些线程耗尽了CPU这些线程在做什么
背景有时,线上集群load会突然飙升,无法响应正常请求。那么引起load飙升的线程究竟在做什么?哪些线程霸占了CPU?可以通过top和jstack命令进行定位。2. 定位步骤1. 使用终端1进入目标机器,执行top命令,默认是进程视图,其中PID是进程号,截图如下:在这里,我们只能看到java进程占用CPU达到115%,那么究竟是那些线程非常耗CPU呢?2. 由于我们要看到线程,在终端1,按下“H”键或者“shift+h”,top视图会切换到线程视图,其中PID是线程号,截图如下:可以发现红框内的线程的CPU使用率非常高,占用CPU时间达到1秒左右,显然不正常,但是这些线程在做什么?3. 打开终端2,使用jstack命令输出这一时刻的线程栈,保存到文件,命名为jstack.log。注意:输出线程栈和保存top命令快照尽量同时进行通过top和jstack确定哪些线程耗尽了CPU?这些线程在做什么
6. jstack 分析出线程id 如何找到进程吗
jstack 分析出线程id 如何找到进程
jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息。
如果是在64位机器上,需要指定选项"-J-d64",Windows的jstack使用方式只支持以下的这种方式:jstack [-l] pid
如果java程序崩溃生成core文件,jstack工具可以用来获得core文件的java stack和native stack的信息,从而可以轻松地知道java程序是如何崩溃和在程序何处发生问题。
另外,jstack工具还可以附属到正在运行的java程序中,看到当时运行的java程序的java stack和native stack的信息, 如果现在运行的java程序呈现hung的状态,jstack是非常有用的。
需要注意的问题:
l 不同的 JAVA虚机的线程 DUMP的创建方法和文件格式是不一样的,不同的 JVM版本, mp信息也有差别。
l 在实际运行中,往往一次 mp的信息,还不足以确认问题。建议产生三次 mp信息,如果每次 mp都指向同一个问题,我们才确定问题的典型性。
2、命令格式
$jstack [ option ] pid
$jstack [ option ] executable core
$jstack [ option ] [server-id@]remote-hostname-or-IP
参数说明:
pid: java应用程序的进程号,一般可以通过jps来获得;
executable:产生core mp的java可执行程序;
core:打印出的core文件;
remote-hostname-or-ip:远程debug服务器的名称或IP;
server-id: 唯一id,假如一台主机上多个远程debug服务;
示例:
$jstack –l 23561
线程分析:
一般情况下,通过jstack输出的线程信息主要包括:jvm自身线程、用户线程等。其中jvm线程会在jvm启动时就会存在。对于用户线程则是在用户访问时才会生成。
7. 虚拟机中不能使用jstack命令吗
找到CPU利用率持续比较高的进程,获取进程号,此处PID为3036
命令:
top
找到上述进程中,CPU利用率比较高的线程号TID(十进制数),此处为3046
命令:
将获取的线程号(十进制数)转换成十六进制,此处为0xb46
6
查看进程PID为3036中
nid为0xb46的线程信息。
8. 怎么jstack命令mp线程信息
一般情况下,通过jstack输出的线程信息主要包括:jvm自身线程、用户线程等。其中jvm线程会在jvm启动时就会存在。对于用户线程则是在用户访问时才会生成。
l jvm线程:
在线程中,有一些 JVM内部的后台线程,来执行譬如垃圾回收,或者低内存的检测等等任务,这些线程往往在JVM初始化的时候就存在
9. 怎样使用jstack诊断Java应用程序故障
首先让我们来了解一下jstack这个命令的作用,jstack
是一个可以返回在应用程序上运行的各种各样线程的一个完整转储的实用程序,您可以使用它查明问题。jstack [-l]
<pid>,jpid可以通过使用jps命令来查看当前Java程序的jpid值,-l是可选参数,它可以显示线程阻塞/死锁情况。
Java代码
/**
* 死锁例子
* @author crane.ding
* @since 2011-3-20
*/
public class DeadLock {
public static void main(String[] args) {
final Object obj_1 = new Object(), obj_2 = new Object();
Thread t1 = new Thread("t1"){
@Override
public void run() {
synchronized (obj_1) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {}
synchronized (obj_2) {
System.out.println("thread t1 done.");
}
}
}
};
Thread t2 = new Thread("t2"){
@Override
public void run() {
synchronized (obj_2) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {}
synchronized (obj_1) {
System.out.println("thread t2 done.");
}
}
}
};
t1.start();
t2.start();
}
}
以上DeadLock类是一个死锁的例子,假使在我们不知情的情况下,运行DeadLock后,发现等了N久都没有在屏幕打印线程完成信息。这个时候我们就可以使用jps查看该程序的jpid值和使用jstack来生产堆栈结果问题。
Linux代码
$ java -cp deadlock.jar DeadLock &
$
Linux代码
$ jps
3076 Jps
448 DeadLock
$ jstack -l 448 > deadlock.jstack
结果文件deadlock.jstack内容如下:
Xml代码
2011-03-20 23:05:20
Full thread mp Java HotSpot(TM) Client VM (19.1-b02 mixed mode, sharing):
"DestroyJavaVM" prio=6 tid=0x00316800 nid=0x9fc waiting on condition [0x00000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"t2" prio=6 tid=0x02bcf000 nid=0xc70 waiting for monitor entry [0x02f6f000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.demo.DeadLock$2.run(DeadLock.java:40)
- waiting to lock <0x22a297a8> (a java.lang.Object)
- locked <0x22a297b0> (a java.lang.Object)
Locked ownable synchronizers:
- None
"t1" prio=6 tid=0x02bce400 nid=0xba0 waiting for monitor entry [0x02f1f000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.demo.DeadLock$1.run(DeadLock.java:25)
- waiting to lock <0x22a297b0> (a java.lang.Object)
- locked <0x22a297a8> (a java.lang.Object)
Locked ownable synchronizers:
- None
"Low Memory Detector" daemon prio=6 tid=0x02bb9400 nid=0xa6c runnable [0x00000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"CompilerThread0" daemon prio=10 tid=0x02bb2800 nid=0xcb8 waiting on condition [0x00000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"Attach Listener" daemon prio=10 tid=0x02bb1000 nid=0x7f4 waiting on condition [0x00000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"Signal Dispatcher" daemon prio=10 tid=0x02bd2800 nid=0xd80 runnable [0x00000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"Finalizer" daemon prio=8 tid=0x02bab000 nid=0xe1c in Object.wait() [0x02d3f000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x229e1148> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)
- locked <0x229e1148> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)
Locked ownable synchronizers:
- None
"Reference Handler" daemon prio=10 tid=0x02ba6800 nid=0xbe0 in Object.wait() [0x02cef000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x229e1048> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:485)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)
- locked <0x229e1048> (a java.lang.ref.Reference$Lock)
Locked ownable synchronizers:
- None
"VM Thread" prio=10 tid=0x02b6a400 nid=0x568 runnable
"VM Periodic Task Thread" prio=10 tid=0x02bc8400 nid=0x75c waiting on condition
JNI global references: 878
Found one Java-level deadlock:
=============================
"t2":
waiting to lock monitor 0x02baaeec (object 0x22a297a8, a java.lang.Object),
which is held by "t1"
"t1":
waiting to lock monitor 0x02baa2bc (object 0x22a297b0, a java.lang.Object),
which is held by "t2"
Java stack information for the threads listed above:
===================================================
"t2":
at com.demo.DeadLock$2.run(DeadLock.java:40)
- waiting to lock <0x22a297a8> (a java.lang.Object)
- locked <0x22a297b0> (a java.lang.Object)
"t1":
at com.demo.DeadLock$1.run(DeadLock.java:25)
- waiting to lock <0x22a297b0> (a java.lang.Object)
- locked <0x22a297a8> (a java.lang.Object)
Found 1 deadlock.
从这个结果文件我们一看到发现了一个死锁,具体是线程t2在等待线程t1,而线程t1在等待线程t2造成的,同时也记录了线程的堆栈和代码行数,通过这个堆栈和行数我们就可以去检查对应的代码块,从而发现问题和解决问题。
10. 如何使用 jstack 分析线程状态
1、上图中可以看出pid为23344的java进程占用了较多的cpu资源;
2、通过top -Hp 23344可以查看该进程下各个线程的cpu使用情况;
上图中可以看出pid为25077的线程占了较多的cpu资源,利用jstack命令可以继续查看该线程当前的堆栈状态。
jstack命令
通过top命令定位到cpu占用率较高的线程之后,继续使用jstack pid命令查看当前java进程的堆栈状态
jstack命令生成的thread mp信息包含了JVM中所有存活的线程,为了分析指定线程,必须找出对应线程的调用栈,应该如何找?
在top命令中,已经获取到了占用cpu资源较高的线程pid,将该pid转成16进制的值,在thread mp中每个线程都有一个nid,找到对应的nid即可;隔段时间再执行一次stack命令获取thread mp,区分两份mp是否有差别,在nid=0x246c的线程调用栈中,发现该线程一直在执行JstackCase类第33行的calculate方法,得到这个信息,就可以检查对应的代码是否有问题。
通过thread mp分析线程状态