java堆栈_java线程的堆栈跟踪之jstack篇
该命令打印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篇相关推荐
- java异常_Java线程池「异常处理」正确姿势:有病就得治
假设我们有一个线程池,由于程序需要,我们向该线程池中提交了好多好多任务,但是 这些任务都没有对异常进行try catch处理,并且运行的时候都抛出了异常 .这会对线程池的运行带来什么影响? 正确答案是 ...
- java 递归 堆栈_Java中的堆栈安全递归
java 递归 堆栈 在本文中,摘自< Java中的函数编程 >一书,我解释了如何使用递归,同时避免了StackOverflow异常的风险. Corecursion正在使用第一步的输出作为 ...
- java 队列和堆栈_Java中的堆栈和队列
java 队列和堆栈 我最近一直在研究一些需要堆栈和队列的Java代码. 使用的选择不是立即显而易见的. 有一个Queue接口,但没有明确的具体实现要使用. 还有一个Stack类,但是javadocs ...
- JAVA 海啸_java线程总结
首先要理解线程首先需要了解一些基本的东西,我们现在所使用的大多数操作系统都属于多任务,分时操作系统.正是由于这种操作系统的出现才有了多线程这个概念.我们使用的windows,linux就属于此列.什么 ...
- java看山不是山_java线程启动原理分析
一.前言 不知道哪位古人说:人生三大境界.第一境界是:看山是山看水是水:第二境界是看山不是山看水不是水:第三境界:看山还是山看水还是水. 其实我想对于任何一门技术的学习都是这样. 形而上下者为之器,形 ...
- future java 原理_Java线程池FutureTask实现原理详解
前言 线程池可以并发执行多个任务,有些时候,我们可能想要跟踪任务的执行结果,甚至在一定时间内,如果任务没有执行完成,我们可能还想要取消任务的执行,为了支持这一特性,ThreadPoolExecutor ...
- java 原子量_JAVA线程10 - 新特性:原子量
一.原子量简介 原子量就是操作变量的操作是"原子的",该操作不可再分,因此是线程安全的. 原子量虽然可以保证单个变量在某一个操作过程的安全,但无法保证你整个代码块,或者整个程序的安 ...
- 线程java作用_java线程介绍(原创)
文章讲解要点 1.线程创建几种方式 2.线程常见设置方法,包括优先级.优先级休眠.停止等 3.多线程间的数据交互与锁机制 4.项目源码下载 线程介绍.png 一.线程创建方式 常见的线程创建方法以下三 ...
- java实例_Java线程方式及实例
简介 线程创建方式由继承Thread类,实现Runnable接口,实现Callable接口通过FutureTask包装,通过线程池来创建,所以本文主要介绍Java线程方式. 继承Thread类 Thr ...
最新文章
- linux io函数,Linux下普通IO文件操作函数---C语言
- java编程器答疑z湖南岚鸿,吐血整理
- Kotlin 学习笔记01
- xml显示浏览器标签_浅析浏览器书签的导入和导出
- C++入门经典-例8.3-子类显示调用父类构造函数
- 关于ubuntu中的inittab文件
- C++中虚函数、纯虚函数、普通函数三者的区别
- matlab设计凸轮轮廓代码_机械设计基础之什么是凸轮机构,分类和常用运动规律是怎么样的?...
- python可以参加哪些竞赛_找出Python竞赛中可达到的分数的程序
- Clickhouse:分区和数值化优化实测
- 推荐几本微积分入门书籍
- Android Studio中竟然还能加入一个程序员鼓励师
- ubuntu system setting no everthing
- 《机器学习-原理、算法与应用》出版了
- Redis的基本操作
- 软件项目中得风险应对策略
- 2.过滤函数-filter/filter-out
- word树状分支图_word绘制树形图
- 电阻式触摸屏的基本结构和驱动原理
- 最快的扫雷记录,初级只需要0.49秒,一眨眼就结束的操作!