一、堆栈信息解读

2013-01-13 11:02:31

Full thread dump Java HotSpot(TM) Client VM (23.1-b03 mixed mode, sharing):

"[ThreadPool Manager] - Idle Thread" daemon prio=6 tid=0x069a3400 nid=0x84 in Object.wait() [0x0795f000]

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

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

- waiting on <0x239102b8> (a org.eclipse.equinox.internal.util.impl.tpt.threadpool.Executor)

at java.lang.Object.wait(Object.java:503)

at org.eclipse.equinox.internal.util.impl.tpt.threadpool.Executor.run(Executor.java:106)

- locked <0x239102b8> (a org.eclipse.equinox.internal.util.impl.tpt.threadpool.Executor)

Locked ownable synchronizers:

- None

1、这个线程的名称为[ThreadPool Manager] - Idle Thread,实际开发过程中使用可以使用Thread对象的setName方法修改;这里可以看出设置线程名字属性的必要性,导出栈信息的时候就有用了,可以通过线程名字方便的定位到问题代码块;

2、优先级为6,不过优先级意义不大,对分析应用帮助不大,Java不推荐修改线程的优先级,所以这里跳过;

3、tid和nid,16进制表示,这两个字段中有一个可以对应到操作系统调度时使用的线程ID,这在Linux下特别有用,因为top -H命令可以输出各个线程的CPU占用率,借助栈信息,可以方便的定位到CPU占用高的线程,这个很有用,在其它平台暂时还看不出什么意义;

4、当前栈顶,为java.lang.Object.wait方法;

5、线程状态,java.lang.Thread.State: WAITING (on object monitor);java.lang.Thread.State是什么?有兴趣的话可以翻看JDK的源码,源码很简单,注释很详细,给出了Java线程可能存在的状态;

NEW,线程对象被new出来,但是还没有调用start方法;

RUNNABLE,线程对象已经被调用了start方法;

BLOCKED,简单的说,线程进入了synchronized关键字标识的同步块,但和4状态有所区别;

WAITING和TIMED_WAITING差不多,一般是调用了对象的wait方法,需要其它线程在特定场景使用notify/notifyAll方法;

TERMINATED,这个状态比较直白,run方法退出运行,即进入这个状态

6、当前线程是否处于同步块内,   Locked ownable synchronizers:,这里值为None,说明当前线程没有处于同步块内。

NEW: The thread is created but has not been processed yet.

RUNNABLE: The thread is occupying the CPU and processing a task. (It may be in WAITING status due to the OS's resource distribution.)

BLOCKED: The thread is waiting for a different thread to release its lock in order to get the monitor lock.

WAITING: The thread is waiting by using a wait, join or park method.

TIMED_WAITING: The thread is waiting by using a sleep, wait, join or park method. (The difference from WAITING is that the maximum waiting time is specified by the method parameter, and WAITING can be relieved by time as well as external changes.)

二、死锁

三、值得关注的对象

Dump文件里,值得关注的线程状态有:

1、死锁,Deadlock(重点关注)

2、执行中,Runnable

3、等待资源,Waiting on condition(重点关注)

4、等待获取监视器,Waiting on monitor entry(重点关注)

5、暂停,Suspended

6、对象等待中,Object.wait()  或 TIMED_WAITING

7、阻塞,Blocked(重点关注)

综合示范一:Waiting to lock 和 Blocked

实例如下:

"RMI TCP Connection(267865)-172.16.5.25" daemon prio=10 tid=0x00007fd508371000 nid=0x55aewaiting for monitor entry [0x00007fd4f8684000]

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

at org.apache.log4j.Category.callAppenders(Category.java:201)

- waiting to lock <0x00000000acf4d0c0>(a org.apache.log4j.Logger)

at org.apache.log4j.Category.forcedLog(Category.java:388)

at org.apache.log4j.Category.log(Category.java:853)

at org.apache.commons.logging.impl.Log4JLogger.warn(Log4JLogger.java:234)

at com.tuan.core.common.lang.cache.remote.SpyMemcachedClient.get(SpyMemcachedClient.java:110)

……

1)线程状态是 Blocked,阻塞状态。说明线程等待资源超时!

2)“ waiting to lock <0x00000000acf4d0c0>”指,线程在等待给这个 0x00000000acf4d0c0 地址上锁(英文可描述为:trying to obtain  0x00000000acf4d0c0 lock)。

3)在 dump 日志里查找字符串 0x00000000acf4d0c0,发现有大量线程都在等待给这个地址上锁。如果能在日志里找到谁获得了这个锁(如locked ),就可以顺藤摸瓜了。

4)“waiting for monitor entry”说明此线程通过 synchronized(obj) {……} 申请进入了临界区,从而进入了下图1中的“Entry Set”队列,但该 obj 对应的 monitor 被其他线程拥有,所以本线程在 Entry Set 队列中等待。

5)第一行里,"RMI TCP Connection(267865)-172.16.5.25"是 Thread Name 。tid指Java Thread id。nid指native线程的id。prio是线程优先级。[0x00007fd4f8684000]是线程栈起始地址。

Dump文件中的线程状态含义及注意事项

含义如下所示:

1、Deadlock:死锁线程,一般指多个线程调用间,进入相互资源占用,导致一直等待无法释放的情况。

2、Runnable:一般指该线程正在执行状态中,该线程占用了资源,正在处理某个请求,有可能正在传递SQL到数据库执行,有可能在对某个文件操作,有可能进行数据类型等转换。

3、Waiting on condition:等待资源,或等待某个条件的发生。具体原因需结合  stacktrace来分析。

(1)如果堆栈信息明确是应用代码,则证明该线程正在等待资源。一般是大量读取某资源,且该资源采用了资源锁的情况下,线程进入等待状态,等待资源的读取。

(2)又或者,正在等待其他线程的执行等。

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

一种情况是网络非常忙,几乎消耗了所有的带宽,仍然有大量数据等待网络读写;

另一种情况也可能是网络空闲,但由于路由等问题,导致包无法正常的到达。

(4)另外一种出现 Wait on condition的常见情况是该线程在 sleep,等待 sleep的时间到了时候,将被唤醒。

4、Blocked:线程阻塞,是指当前线程执行过程中,所需要的资源长时间等待却一直未能获取到,被容器的线程管理器标识为阻塞状态,可以理解为等待资源超时的线程。

5、Waiting for monitor entry 和 in Object.wait():Monitor是  Java中用以实现线程之间的互斥与协作的主要手段,它可以看成是对象或者 Class的锁。每一个对象都有,也仅有一个 monitor。从下图1中可以看出,每个 Monitor在某个时刻,只能被一个线程拥有,该线程就是 “Active Thread”,而其它线程都是 “Waiting Thread”,分别在两个队列 “ Entry Set”和 “Wait Set”里面等候。在 “Entry Set”中等待的线程状态是 “Waiting for monitor entry”,而在 “Wait Set”中等待的线程状态是  “in Object.wait()”

综合示范二:Waiting on condition和 TIMED_WAITING

实例如下:

"RMI TCP Connection(idle)" daemon prio=10 tid=0x00007fd50834e800 nid=0x56b2 waiting on condition[0x00007fd4f1a59000]

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

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

- parking to wait for  <0x00000000acd84de8>(a java.util.concurrent.SynchronousQueue$TransferStack)

at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:198)

at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:424)

at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:323)

at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:874)

at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:945)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)

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

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)别的就看不出来了。

综合示范三:in Obejct.wait()和 TIMED_WAITING

实例如下:

"RMI RenewClean-[172.16.5.19:28475]" daemon prio=10 tid=0x0000000041428800 nid=0xb09 in Object.wait()[0x00007f34f4bd0000]

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

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

- waiting on <0x00000000aa672478> (a java.lang.ref.ReferenceQueue$Lock)

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

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

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

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

1)“TIMED_WAITING (on object monitor)”,对于本例而言,是因为本线程调用了 java.lang.Object.wait(long timeout) 而进入等待状态。

2)“Wait Set”中等待的线程状态就是“ in Object.wait() ”。当线程获得了 Monitor,进入了临界区之后,如果发现线程继续运行的条件没有满足,它则调用对象(一般就是被 synchronized 的对象)的 wait() 方法,放弃了 Monitor,进入 “Wait Set”队列。只有当别的线程在该对象上调用了  notify() 或者 notifyAll() ,“ Wait Set”队列中线程才得到机会去竞争,但是只有一个线程获得对象的 Monitor,恢复到运行态。

3)RMI RenewClean 是 DGCClient 的一部分。DGC 指的是 Distributed GC,即分布式垃圾回收。

4)请注意,是先 locked <0x00000000aa672478>,后 waiting on <0x00000000aa672478>,之所以先锁再等同一个对象,请看下面它的代码实现:

static private class  Lock { };

private Lock lock = new Lock();

public Reference extends T> remove(long timeout)

{

synchronized (lock) {

Reference extends T> r = reallyPoll();

if (r != null) return r;

for (;;) {

lock.wait(timeout);

r = reallyPoll();

……

}

}

即,线程的执行中,先用 synchronized 获得了这个对象的 Monitor(对应于  locked <0x00000000aa672478> );当执行到 lock.wait(timeout);,线程就放弃了 Monitor 的所有权,进入“Wait Set”队列(对应于  waiting on <0x00000000aa672478> )。

5)从堆栈信息看,是正在清理 remote references to remote objects ,引用的租约到了,分布式垃圾回收在逐一清理呢。

参见:http://blog.csdn.net/kobejayandy/article/details/36030547

jstat 用来统计 gc 的相关信息:各代空间大小、比例、gc 时间等。示例:jstat -gc 输出:

关于jstat详情请参见:http://blog.csdn.net/chaofanwei/article/details/11758395

java 堆栈信息分析_堆栈信息分析相关推荐

  1. python英文文本情感分析_舆情信息浩如烟海?看看如何用Python进行英文文本的情感分析...

    市场每天都在生成海量的舆情信息,这些信息可以帮助我们识别市场情绪的转变.如果只是人工地去跟踪大量的舆论和研报显然缺乏效率.我们可以试试让机器来完成这个工作. 数据科学在数值领域中很常见,但这个不断壮大 ...

  2. 创意产品 分析_使用联合分析来发展创意

    创意产品 分析 Advertising finds itself in a tenacious spot these days serving two masters: creativity and ...

  3. python灰色关联度分析_灰色关联分析法 python

    广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! 本文2290字,预计阅读需10分钟: 关联分析(association anal ...

  4. 转录组分析_高级转录组分析和R数据可视化

    封面来源:https://www.zhihu.com/question/304747766 常规转录组是我们最常接触到的一种高通量测序数据类型,其实验方法成熟,花费较低,是大部分CNS必备的技术,以后 ...

  5. 上海交通大学出版社python教材答案学生信息管理系统_学生信息管理系统(最终版)...

    <学生信息管理系统.doc>由会员分享,可免费在线阅读全文,更多与<学生信息管理系统(最终版)>相关文档资源请在帮帮文库(www.woc88.com)数亿文档库存里搜索. 1. ...

  6. python酒店评论分析_酒店舆情分析

    Python进行携程酒店评论舆情分析 第一步:分析设计 我们是对酒店进行舆情分析,所有我们的核心是酒店的评论数据:对住客的评论数据进行特征提取,通过住客对酒店的评分,对数据进行分类,并使用朴素贝叶斯算 ...

  7. 用Mysql做个人信息管理系统_个人信息管理系统数据库设计精选.doc

    个人信息管理系统数据库设计精选 河海大学计算机及信息工程学院(常州) 数据库课程设计 学年学期 2012第二学期 项目名称 个人信息管理 项目组员 曹清云.陈天昊 指导教师 景雪琴 组号:8 目 录 ...

  8. java对微博评论进行分析_微博上分析情感的_中文情感分析java_中文微博情感分析...

    目前,社会正处于一个微博崛起的时代,一切有关于微博的问题都被社会广泛关注,并得到了工业界和学术界的高度重视.微博从出现以来,取得了良好的发展,并拥有大众的普遍关注和应用.微博的超大信息量和高速度的更新 ...

  9. java解析五元组_抓包分析提取五元组

    网络中每个通信实体的 socket 是用一个三元组标识的.三元组往往称为半相关 三元组指的是:协议族(地址族),网络地址.和传输层端口 ( Ipv4 ). 通信双方的一个连接是用网络五元组来标识的,它 ...

最新文章

  1. 算法 求两个自然数的最小公倍数 C
  2. 深入了解以太坊虚拟机
  3. Git实战(二)原理
  4. 为什么中国有很大一部分人不愿使用windows10?
  5. html+css做的丝带标签
  6. 机器学习项目完整案例:预测区域的房价中位数
  7. [转]Unix awk完全使用手册
  8. Nhibernate(1)续
  9. Android 资源(Resources)访问
  10. Prometheus Operator 架构 - 每天5分钟玩转 Docker 容器技术(178)
  11. HttpContext.Current
  12. 2018大学计算机答案,2018年大学计算机基础试题及答案
  13. WPF界面设计风格资源库
  14. 运放的电压比较器电路
  15. YOLOv4 改进 | 记录如何一步一步改进YOLOv4到自己的数据集(性能、速度炸裂)
  16. 2021阿里云双11云服务器配置表汇总!
  17. html期末大作业~自制崩坏3网站(附原码)
  18. QQ工具手机软件+实用小软件+恶搞小软件合集
  19. 大一python基础编程试卷_python--大一期末测试题(含答案)
  20. Qt国际化详细步骤(手把手教你如何国际化)

热门文章

  1. 对抗学习中GAN网络详解
  2. 人工智能基础:迁移学习对抗学习简述
  3. 关于Oracle数据库varchar2字段超过4000的截取处理
  4. AWS API Gateway与AWS Lambda代理集成构建REST API
  5. FB潜在顾客表单找不到怎么回事?
  6. 自组织神经网络:Kohonen网络训练算法
  7. SC-FDM和OFDM的区别
  8. 手把手教你我是如何用H5制作工具在微信上宣传我的店铺
  9. OpenFlow:简述OpenFlow协议的演进
  10. 伦敦金走势中一个tick是多少