美文网首页
jstack的使用

jstack的使用

作者: 黄二的NPE | 来源:发表于2018-03-31 12:49 被阅读190次
  • jstack简介

通过jstack,我们可以轻松得知jvm中各个线程的工作情况.

  • 工作情况

jstack -l pid (查出某个进程中运行的所有线程)

利用ps -aux 找出我们的java线程41,然后再用jstack -l 41,就可以查看jvm此刻运行的所有线程.

下面是截取的两个jvm运行的普通线程,一个是守护线程,另外一个是用户线程.
守护线程 守护线程是指给程序提供通用性支持的线程,他不属于程序,gc就是一个很称职的守护线程.守护线程是为用户线程提供服务的,也就是说如果没有用户线程,守护线程就没有存活下去的意义,在jstack中查出来的线程信息中,守护线程有个 daemon 的标志
用户线程 用户线程通常是程序自己开启的.jvm会随着所有的用户程序关闭而关闭

在下面的线程信息中 :
HikariPool-1 connection closer是线程的名字,在Java中可以通过Thread.currentThread().getName()来查看线程名字
prio应该是线程的优先级
tid jvm中的线程id
nid tid映射的操作系统中的线程id,非常有用,不过这里是用16进制的表示, 可以通过 printf "%x\n" 十进制数字 查找一个十进制数字的十六进制表示
0x00007fa735a2a000 线程栈的起始地址
TIMED_WAITING 线程状态
0x00000006e941b160 资源名称,等待某个资源被释放,说明有其他线程锁住了该资源,一般是 locked <0x00000006e941b160>

线程状态

线程状态分析图
  1. RUNNABLE 一个程序可能会有很多个线程同时进行,但是我们的cpu核数是有限的,所以操作系统会让CPU在这些线程上面来回的切换执行,每次执行一个时间片的时间,获得时间片在执行的线程的线程状态就是RUNNING, 而那些没有获得时间片而没有执行的线程就是RUNNABLE
  2. RUNNING 同上
  3. BLOCKED 线程在RUNNING期间遇到synchronized字段被锁住了,在它的线程中会有wait for lock(资源名) 的信息,而那个获得锁的线程中会有 locked(资源名)的信息
  4. WAITING 线程调用了object.wait()或者join()的方法,等待其他线程notify()/notifyAll()唤醒,他在等待资源,可能在等待网络,也可能是在等待IO,并且一般在synchronized块里面执行, 当唤醒以后需要再次获得锁
  5. TIMED_WAITING 类比WAITING, 不同的是他不需要notify()/notifyAll()唤醒,时间到了他就会自动唤醒,可以用Thread.sleep()来模拟.

"HikariPool-1 connection closer①" daemon prio=10② tid=0x00007fa688002800③ nid=0x32fd④ waiting on condition [0x00007fa735a2a000④]
java.lang.Thread.State: TIMED_WAITING (parking)⑤
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000006e6eaee28>⑥ (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:226)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2082)
at java.util.concurrent.LinkedBlockingQueue.poll(LinkedBlockingQueue.java:467)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1068)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Locked ownable synchronizers:
- None

"ActiveMQ Session Task-241" prio=10 tid=0x00007fa6f0818800 nid=0x31a3 waiting on condition [0x00007fa735967000]
java.lang.Thread.State: TIMED_WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000006e9103ab0> (a java.util.concurrent.SynchronousQueue$TransferStack)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:226)
at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:359)
at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:942)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1068)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Locked ownable synchronizers:
- None

  • 利用jstack查看哪段代码最占CPU

假如java进程经常出现卡慢,cpu经常会爆满,这时候我们考虑一下是否是我们某些线程太占cpu,导致其他线程不能好好工作.可以通过以下步骤观察

  1. top 观察是否是java进程的CPU占用最高
  2. 获取java的进程号
  • 直接从top命令中获取,或者linux中可以用 ps -aux | grep java 获得 PID
  • window 我们可以用 cmd 输入jvisualvm 打开 java visual VM ,观察左边的进程信息来获取java的pid
  1. 运用 top -Hp pid 来观察是哪个线程nid的CPU占用最高
  2. 把 3 中获取的线程id 转成 16进制, 如果不会口算,可以用printf "%x\n" 10进制 来获得新的nid
  3. 用 jstack -l pid | grep -A 10 'nid= nid(4步骤获取的nid)' 得知哪个进程最占用CPU了

相关文章

  • jstack使用

    使用jstack分析指定应用线程使用异常排除。 使用jstack命令dump线程信息,例如查看Pid为3117的进...

  • jstack的使用

    jstack简介 通过jstack,我们可以轻松得知jvm中各个线程的工作情况. 工作情况 jstack -l p...

  • jstack的使用

    jstack命令主要打印指定Java进程的线程堆栈跟踪信息。它是一个很有用的命令。 检测死锁 编写一个导致死锁的简...

  • jstack的使用

    参考来源[https://www.cnblogs.com/yangzhixue/p/11989863.html] ...

  • 【Kafka】排查进程无法Jstack

    1. 背景 通过jstack分析kafka堆栈信息时,发现jstack无法使用,并且提示如下异常: 2. 分析 查...

  • jstack使用小结

    搬运自https://www.toutiao.com/i6664464807451689475/ jstack小工...

  • 分析程序死锁及定位

    检测程序死锁 可以使用jstack命令, jstack you_pid进程的pid可以在任务管理器中找到,你也可以...

  • [转]jstack线程dump输出状态解释

    执行jstack命令,将得到进程的堆栈信息。我一般使用jstack -l pid来得到长列表,显示其详细信息。有时...

  • 死锁问题排查

    首先使用jps查询进程ID然后使用jstack和进程ID查询堆栈日志信息。

  • jstack命令解析

    jstack用法 jstack查看输出 jstack统计线程数 jstack检测死锁 死锁代码 死锁日志 jsta...

网友评论

      本文标题:jstack的使用

      本文链接:https://www.haomeiwen.com/subject/rvmwcftx.html