Java线程Dump分析工具--jstack

Java线程Dump分析工具--jstack
  jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息,如果是在64位机器上,需要指定选项"-J-d64",Windows的jstack使用方式只支持以下的这种方式:
     jstack [-l][F] pid
     如果java程序崩溃生成core文件,jstack工具可以用来获得core文件的java stack和native stack的信息,从而可以轻松地知道java程序是如何崩溃和在程序何处发生问题。另外,jstack工具还可以附属到正在运行的java程序中,看到当时运行的java程序的java stack和native stack的信息, 如果现在运行的java程序呈现hung的状态,jstack是非常有用的。进程处于hung死状态可以用-F强制打出stack。
     dump 文件里,值得关注的线程状态有:
     死锁,Deadlock(重点关注)
     执行中,Runnable 
     等待资源,Waiting on condition(重点关注)
     等待获取监视器,Waiting on monitor entry(重点关注)
     暂停,Suspended
     对象等待中,Object.wait() 或 TIMED_WAITING
     阻塞,Blocked(重点关注)
     停止,Parked

在摘了另一篇博客的三种场景:

实例一:Waiting to lock 和 Blocked

"RMI TCP Connection(267865)-172.16.5.25" daemon prio=10 tid=0x00007fd508371000 nid=0x55ae waiting 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 < 0x00000000acf4d0c0 >),就可以顺藤摸瓜了。
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]是线程栈起始地址。
实例二: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/fenglibing/article/details/6411940
三种实例:http://www.cnblogs.com/zhengyun_ustc/archive/2013/01/06/dumpanalysis.html

本页内容版权归属为原作者,如有侵犯您的权益,请通知我们删除。

java spring整合websocket - 2016-09-21 17:09:03

这几天项目中需要整合websocket来支持业务,从网上看了好多资料。但是都很杂乱,我尝试了好多回,走了很多弯路,跳了很多坑~~~~~~。通过两天的调试终于成功!!!现在把调试步骤和容易出现的问题都列出来,让和我这样的新手有点帮助。开始上代码......... 【 备注:spring的版本4.0+ ,tomcat :7.50 + , jdk:1.8 】 java Spring 整合 websocket 有两种方法 : 1:配置方法 [网上有很多] (地址: http://blog.csdn.net/sti

Java命令行classpath的设置 - 2016-09-21 17:09:03

在练习JavaDB Embedded模式的Java编程时候,直接用编辑器开发,所以需要用平时不怎么用的命令行来编译代码,按照普通的方式进行编译之后,开始运行,结果弹出错误提示。 java -classpath derby.jar JavaDBTest 错误: 找不到或无法加载主类 JavaDBTest 想不通是怎么回事。后来发现,需要将当前目录也加入到ClassPath中 java -classpath .;derby.jar JavaDBTest 这样才能成功运行 Load the EmbeddedDri

java 虚拟机-内存管理 - 2016-09-21 14:09:23

      本地方法 非java代码实现的java方法,使用native关键字,除abstract外可与java关键字连用 程序计数器 可以看作是当前线程所执行的字节码的行号指示器。字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支,循环,跳转,异常处理,线程恢复等基础功能。该区域时java虚拟机规范中没有规定outofmeroryError情况的区域 虚拟机栈   1、生命周期同线程一致 2、程序员通常指的栈内存区,更确切的是指虚拟机栈中的局部变量表部分 3、局部变量表存
jAVA基础 提高文件复制性能之多线程复制文件 利用IO流中的随机访问文件 RandomAccessFile 和文件通道 FileChanne 复制文件可大大提高文件的读写效率,在此基础上利用多线程复制文件使其性能更优。因线程的个数可根据文件的大小及需求而定。其大概原理是根据给定的线程个数,将文件分段,每个线程负责的数据大小=文件长度/线程个数,将不能除尽的部分留给最后一段文件所分配的线程处理。以下是实现代码及自己理解的注释,多有偏差请见谅。下面是兄弟连java培训总结的一些代码:供参考。 程序实现类代码
这个是我一个技术相当好的哥们去面试的时候碰到的奇葩问题,那天,这个面试官的答案是不能。后来就带着这个问题去国内外的论坛上搜了一把,也是各说纷纭,实在是没有一个统一的答案,简直有点公说公有理,婆说婆有理的架势。     几个意见大致如下,第一,不能,因为“进程是CPU进行调度的单位,而JVM是一个进程,于是就只能跑在一个CPU上”。第二,“进程是CPU进行调度的单位,这没错,但是OS负责将一个进程在不同的CPU上调度到另外一个CPU上,而这个进程,则是由不同的线程构成的,那么说,线程还是在不同的CPU上运行了
1、一个简单的订单号生成器: 从代码可以看出: long orderNo = (Long.parseLong((date))) * 10000;   orderNo += orderNum + Long.parseLong(RandomStringUtils.randomNumeric(3)); 每毫秒可以保证,10000-999个订单号不重复。     import java.text.SimpleDateFormat;import java.util.Date;import org.apache.co
Java是世界上最流行的程序语言,从1995年问世以来,Java的生态系统在一直在蓬勃的发展着。作为一门健壮的技术,Java社区为广大开发者提供了包括框架、库、web开发sdk、JVM语言等资源。在各种科技行业都能够找到关于Java编程的相关资源,这就是为什么Java会如此受人喜爱。 在今天,发达的网络技术推动了Java的发展,越来越多的人选择在网上学习,查看技术大牛的博客并进行交流成为了日常学习的一个重要手段。在这里,我整理了国外最流行的十大Java技术博客,它们都是由Java技术专家维护的,无论是初学
druid是号称目前最好的java数据库连接池,温少写点代码中有很多设计模式的思想,其中最重要的一个就是filter-chain设计模式给druid所带来的可扩展性。对此,我很感兴趣,并希望日后借鉴,所以看了看他的源码,以此记录一下。 druid中设计到filter-chain设计模式的类或接口主要有一下几个Filter、FilterAdapter、FilterChain、FilterChainImpl、FilterEventAdapter、FilterManager 以及举例讲讲两个具体的filter:

mysql外键实战 - 2016-09-21 14:09:05

一、基本概念 1、MySQL中“键”和“索引”的定义相同,所以外键和主键一样也是索引的一种。不同的是MySQL会自动为所有表的主键进行索引,但是外键字段必须由用户进行明确的索引。用于外键关系的字段必须在所有的参照表中进行明确地索引,InnoDB不能自动地创建索引。 2、外键可以是一对一的,一个表的记录只能与另一个表的一条记录连接,或者是一对多的,一个表的记录与另一个表的多条记录连接。 3、如果需要更好的性能,并且不需要完整性检查,可以选择使用MyISAM表类型,如果想要在MySQL中根据参照完整性来建立表
会联网前沿技术文档,各大公司技术架构,欢迎各位浏览!!!网址: http://dwz.cn/4bwqKb