首页 > 编程知识 正文

Linux查看线程状态,java jstack

时间:2023-05-06 06:22:53 阅读:160573 作者:4834

从3http://www.cn blogs.com/ne xiyi/p/Java _ thread _ jstack.html

jstack线程状态jstack线程应该关注的线程的状态是死锁、死锁(Deadlock ) (在重点执行中,Runnable等待资源,等待获取等待条件)监视器。 Waiting on monitor entry (重点关注)等待Suspended对象时,Object.wait ()或TIMED_WAITING将停止(阻止),Parked (阻止)

综合示范一(Waiting to lock和Blocked实例如下(RMITCPconnection ) 267865 ) )。 - 172.16.5.25 ' daemon prio=10 tid=0x 00007 FD 508371000 NID=0x 55 aewaitingformonitorentry [0x 00007 fd4f 8684000 ] Java.lang.thread.state : blocked (onobjectmonitor ) atorg.Apache.log4j.category.call appenders ) category.j ate ache.log4j.logger ) atorg.Apache.log4j.category.forced log ) category atorg.Apache.log4j.category.log j logger.log4j atcom.Tuan.core.com mon.lang.cache.remote.spymemcachedclient.get (spymemcachedclient.Java 3360600 ) 2 )“waitingtolock0x0000000ACF4d0”表示线程正在等待锁定到此0x00000000acf4d0c0地址(trying to obtain0x 0000000 ACF 4d0) 3 )在dump日志中查找字符串0x00000000acf4d0c0,发现大量线程正在等待对此地址上锁。 如果能在日志中发现是谁得到了这把密钥(例如,locked0x00000000acf4d0c0),就能摸摸芋公式。 4 ) " waiting for monitor entry "表示该线程通过同步(obj )…}进入临界区,进入下面图1中的" Entry Set "队列,但与此obj相对应本线程是entritor中的5 )第一行,' RMITCPconnection(267865 )-172.16.5.25 '为Thread Name。 tid是Java Thread id。 nid是native线程的id。 prio是线程的优先级。 [0x00007fd4f8684000 ]是线程堆栈的起始地址。 Dump文件线程状态的含义和注意事项的含义如下。

Deadlock :死锁线程一般是指多个线程在调用期间进入相互资源占有,持续等待未释放的情况。 Runnable :通常,您可能正在转换某个线程正在运行、该线程正在处理资源、正在处理某个请求、将SQL传递给数据库并正在执行、正在处理某个文件、数据类型等等待条件:等待资源或等待条件发生。 具体原因需结合stacktrace进行分析。 如果知道堆栈信息是APP应用程序代码,则证明线程正在等待资源。 通常,如果大量读取某个资源,并且该资源采用资源锁定,则线程将处于等待状态,等待读取资源。 或者,正在等待其他线程的执行等。 如果发现有大量线程在等待操作中,则从线程堆栈的角度来看,它们正在等待读写网络。 这可能是网络瓶颈的征兆。 线程无法执行,因为网络被阻止。 一个是网络非常繁忙,几乎消耗了所有的带宽,还有大量的数据等待读写网络。 另一种情况是互联网可能是空的,因为路

由等问题,导致包无法正常的到达。 另外一种出现 Wait on condition的常见情况是该线程在 sleep,等待 sleep的时间到了时候,将被唤醒。 Blocked:线程阻塞,是指当前线程执行过程中,所需要的资源长时间等待却一直未能获取到,被容器的线程管理器标识为阻塞状态,可以理解为等待资源超时的线程。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()”。

图1 A Java Monitor

 

综合示范二:W aiting 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 ,引用的租约到了,分布式垃圾回收在逐一清理呢。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。