该命令打印java线程的堆栈跟踪,可以得知哪些线程被阻塞或正等待,以便于查找如线程死锁的原因

用法:

jstack [ option ] pid

jstack [ option ] executable core

jstack [ option ] [server-id@]remote-hostname-or-IP

常用选项:

-F 当’jstack [-l] pid’没有相应的时候强制打印栈信息

-l 长列表. 打印关于锁的附加信息,例如属于java.util.concurrent的ownable synchronizers列表.

-m 打印java和native c/c++框架的所有栈信息.

常用参数:

core 将被打印信息的core dump文件

remote-hostname-or-IP 远程debug服务的主机名或ip

server-id 唯一id,假如一台主机上多个远程debug服务

id 需要被打印配置信息的java进程id,可以用jps查询

2.tomcat线程状态的种类

1.线程状态为“waiting on condition”

说明它在等待另一个条件的发生,来把自己唤醒,或者干脆它是调用了 sleep(N)。

此时线程状态大致为以下几种:

?java.lang.Thread.State: WAITING (parking):一直等那个条件发生;

?java.lang.Thread.State: TIMED_WAITING (parking或sleeping):定时的,那个条件不到来,也将定时唤醒自己。

如果大量线程在“waiting on condition”:

可能是它们又跑去获取第三方资源,尤其是第三方网络资源,迟迟获取不到Response,导致大量线程进入等待状态。

所以如果你发现有大量的线程都处在 Wait on condition,从线程堆栈看,正等待网络读写,这可能是一个网络瓶颈的征兆,因为网络阻塞导致线程无法执行。

实例1:定时的,那个条件不到来,也将定时唤醒自己。

"ContainerBackgroundProcessor[StandardEngine[Catalina]]" daemon prio=10 tid=0x00007f67a419a800 nid=0x4655 waiting on condition [0x00007f679a3fd000]

java.lang.Thread.State: TIMED_WAITING (sleeping)

at java.lang.Thread.sleep(Native Method)

at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1510)

at java.lang.Thread.run(Thread.java:745)

实例2:一直等那个条件发生

"http-nio-8080-exec-1" daemon prio=10 tid=0x00007f677ca95800 nid=0x46a8 waiting on condition [0x00007f679a47e000]

java.lang.Thread.State: WAITING (parking)

at sun.misc.Unsafe.park(Native Method)

- parking to wait for <0x00000007a0399b28> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)

at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)

at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2043)

at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)

at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:104)

at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:32)

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 org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)

at java.lang.Thread.run(Thread.java:745)

1)“TIMED_WAITING (parking)”中的 timed_waiting 指等待状态,但这里指定了时间,到达指定的时间后自动退出等待状态;parking指线程处于挂起中。

2)“waiting on condition”需要与堆栈中的“parking to wait for <0x00000000acd84de8> (a java.util.concurrent.SynchronousQueue$TransferStack)” 结合来看。首先,本线程肯定是在等待某个条件的发生,来把自己唤醒。其次,SynchronousQueue 并不是一个队列,只是线程之间移交信息的机制,当我们把一个元素放入到 SynchronousQueue 中时必须有另一个线程正在等待接受移交的任务,因此这就是本线程在等待的条件

实例3

"RMI RenewClean-[10.24.189.110:1919]" daemon prio=10 tid=0x00007f6764ee1000 nid=0x4764 in Object.wait() [0x00007f67859b9000]

java.lang.Thread.State: TIMED_WAITING (on object monitor)

at java.lang.Object.wait(Native Method)

at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:135)

- locked <0x00000007a1bca328> (a java.lang.ref.ReferenceQueue$Lock)

at sun.rmi.transport.DGCClient$EndpointEntry$RenewCleanThread.run(DGCClient.java:535)

at java.lang.Thread.run(Thread.java:745)

实例4

"Timer-8" daemon prio=10 tid=0x00007f676c032800 nid=0x5b7d in Object.wait() [0x00007f6785833000]

java.lang.Thread.State: TIMED_WAITING (on object monitor)

at java.lang.Object.wait(Native Method)

at java.util.TimerThread.mainLoop(Timer.java:552)

- locked <0x00000007b47c7630> (a java.util.TaskQueue)

at java.util.TimerThread.run(Timer.java:505)

2.线程状态为“waiting for monitor entry”:

意味着它 在等待进入一个临界区 ,所以它在”Entry Set“队列中等待。

此时线程状态一般都是 Blocked:

java.lang.Thread.State: BLOCKED (on object monitor)

3.如果大量线程在“waiting for monitor entry”:

可能是一个全局锁阻塞住了大量线程。

如果短时间内打印的 thread dump 文件反映,随着时间流逝,waiting for monitor entry 的线程越来越多,没有减少的趋势,可能意味着某些线程在临界区里呆的时间太长了,以至于越来越多新线程迟迟无法进入临界区。

3.实例操作:

[root@tomcat01 conf]# jps

13886 Jps

21147 Application

13614 Bootstrap

[root@tomcat01 conf]# jstack 13614|grep "java.lang.Thread.State"|grep parking

java.lang.Thread.State: WAITING (parking)

java.lang.Thread.State: WAITING (parking)

java.lang.Thread.State: WAITING (parking)

java.lang.Thread.State: WAITING (parking)

java.lang.Thread.State: WAITING (parking)

java.lang.Thread.State: WAITING (parking)

java.lang.Thread.State: WAITING (parking)

java.lang.Thread.State: WAITING (parking)

java.lang.Thread.State: WAITING (parking)

java.lang.Thread.State: WAITING (parking)

java.lang.Thread.State: WAITING (parking)

java.lang.Thread.State: WAITING (parking)

java.lang.Thread.State: WAITING (parking)

java.lang.Thread.State: WAITING (parking)

java.lang.Thread.State: WAITING (parking)

java.lang.Thread.State: WAITING (parking)

java.lang.Thread.State: WAITING (parking)

java.lang.Thread.State: WAITING (parking)

java.lang.Thread.State: WAITING (parking)

java.lang.Thread.State: WAITING (parking)

java.lang.Thread.State: WAITING (parking)

java.lang.Thread.State: WAITING (parking)

java.lang.Thread.State: WAITING (parking)

java.lang.Thread.State: WAITING (parking)

java.lang.Thread.State: WAITING (parking)

java.lang.Thread.State: WAITING (parking)

java.lang.Thread.State: WAITING (parking)

java.lang.Thread.State: WAITING (parking)

java.lang.Thread.State: WAITING (parking)

java.lang.Thread.State: WAITING (parking)

java.lang.Thread.State: WAITING (parking)

java.lang.Thread.State: WAITING (parking)

java.lang.Thread.State: WAITING (parking)

java.lang.Thread.State: WAITING (parking)

java.lang.Thread.State: WAITING (parking)

java.lang.Thread.State: WAITING (parking)

java.lang.Thread.State: WAITING (parking)

java.lang.Thread.State: WAITING (parking)

java.lang.Thread.State: WAITING (parking)

java.lang.Thread.State: WAITING (parking)

java.lang.Thread.State: TIMED_WAITING (parking)

[root@tomcat01 conf]# jstack 13614|grep "java.lang.Thread.State"|grep parking|wc -l

41

java.lang.Thread.State: WAITING (parking) 的数量等于minsparethread最小空闲的线程数的数值

检查 是否存在死锁

[root@VM_82_178_redhat ~]# jstack -l -F 7523

Attaching to process ID 7523, please wait...

Debugger attached successfully.

Server compiler detected.

JVM version is 25.60-b23

Deadlock Detection:

**No deadlocks found**.

java堆栈_java线程的堆栈跟踪之jstack篇相关推荐

  1. java异常_Java线程池「异常处理」正确姿势:有病就得治

    假设我们有一个线程池,由于程序需要,我们向该线程池中提交了好多好多任务,但是 这些任务都没有对异常进行try catch处理,并且运行的时候都抛出了异常 .这会对线程池的运行带来什么影响? 正确答案是 ...

  2. java 递归 堆栈_Java中的堆栈安全递归

    java 递归 堆栈 在本文中,摘自< Java中的函数编程 >一书,我解释了如何使用递归,同时避免了StackOverflow异常的风险. Corecursion正在使用第一步的输出作为 ...

  3. java 队列和堆栈_Java中的堆栈和队列

    java 队列和堆栈 我最近一直在研究一些需要堆栈和队列的Java代码. 使用的选择不是立即显而易见的. 有一个Queue接口,但没有明确的具体实现要使用. 还有一个Stack类,但是javadocs ...

  4. JAVA 海啸_java线程总结

    首先要理解线程首先需要了解一些基本的东西,我们现在所使用的大多数操作系统都属于多任务,分时操作系统.正是由于这种操作系统的出现才有了多线程这个概念.我们使用的windows,linux就属于此列.什么 ...

  5. java看山不是山_java线程启动原理分析

    一.前言 不知道哪位古人说:人生三大境界.第一境界是:看山是山看水是水:第二境界是看山不是山看水不是水:第三境界:看山还是山看水还是水. 其实我想对于任何一门技术的学习都是这样. 形而上下者为之器,形 ...

  6. future java 原理_Java线程池FutureTask实现原理详解

    前言 线程池可以并发执行多个任务,有些时候,我们可能想要跟踪任务的执行结果,甚至在一定时间内,如果任务没有执行完成,我们可能还想要取消任务的执行,为了支持这一特性,ThreadPoolExecutor ...

  7. java 原子量_JAVA线程10 - 新特性:原子量

    一.原子量简介 原子量就是操作变量的操作是"原子的",该操作不可再分,因此是线程安全的. 原子量虽然可以保证单个变量在某一个操作过程的安全,但无法保证你整个代码块,或者整个程序的安 ...

  8. 线程java作用_java线程介绍(原创)

    文章讲解要点 1.线程创建几种方式 2.线程常见设置方法,包括优先级.优先级休眠.停止等 3.多线程间的数据交互与锁机制 4.项目源码下载 线程介绍.png 一.线程创建方式 常见的线程创建方法以下三 ...

  9. java实例_Java线程方式及实例

    简介 线程创建方式由继承Thread类,实现Runnable接口,实现Callable接口通过FutureTask包装,通过线程池来创建,所以本文主要介绍Java线程方式. 继承Thread类 Thr ...

最新文章

  1. linux io函数,Linux下普通IO文件操作函数---C语言
  2. java编程器答疑z湖南岚鸿,吐血整理
  3. Kotlin 学习笔记01
  4. xml显示浏览器标签_浅析浏览器书签的导入和导出
  5. C++入门经典-例8.3-子类显示调用父类构造函数
  6. 关于ubuntu中的inittab文件
  7. C++中虚函数、纯虚函数、普通函数三者的区别
  8. matlab设计凸轮轮廓代码_机械设计基础之什么是凸轮机构,分类和常用运动规律是怎么样的?...
  9. python可以参加哪些竞赛_找出Python竞赛中可达到的分数的程序
  10. Clickhouse:分区和数值化优化实测
  11. 推荐几本微积分入门书籍
  12. Android Studio中竟然还能加入一个程序员鼓励师
  13. ubuntu system setting no everthing
  14. 《机器学习-原理、算法与应用》出版了
  15. Redis的基本操作
  16. 软件项目中得风险应对策略
  17. 2.过滤函数-filter/filter-out
  18. word树状分支图_word绘制树形图
  19. 电阻式触摸屏的基本结构和驱动原理
  20. 最快的扫雷记录,初级只需要0.49秒,一眨眼就结束的操作!

热门文章

  1. C/C++ debug(四)
  2. Python Tricks(六)—— 删除一个可迭代序列中等于某值的全部元素
  3. Git 基础(八)—— 分支管理
  4. C基础——文本格式和二进制格式的区别
  5. python画动态图-Python使用matplotlib画动态图
  6. python常用代码总结-python个人总结
  7. 艾媒2018年度手机输入法报告出炉:百度输入法是语音识别最准的输入法
  8. java 可变 不可变_java中的不可变类型的探究
  9. 【java笔记】函数式编程
  10. 【数据结构和算法笔记】用c和c++分别实现二叉搜索树