java8 jstack_JDK自带工具之jstack

jstack是java虚拟机自带的一种堆栈跟踪工具。jstack位于java的bin目录下,主要利用JVM内建的指令对Java应用程序的资源和性能进行实时的命令行的监控,包括了对Heap

size和垃圾回收状况的监控。

Jstat可以用来监视VM内存内的各种堆和非堆的大小及其内存使用量。

1、Jstack命令格式

jstack [ option ] pid

2、常用参数

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

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

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

-h | -help打印帮助信息

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

3、生成死锁(deadlock)的源代码

package com.jdkTools;

/**

*简单的应用,供测试JDK自带的jstack使用 本应用会造成deadlock,可能会导致系统崩溃

*逻辑:一旦两个线程互相等待的局面出现,死锁(deadlock)就发生了

*

* @author范芳铭

*/

public class EasyJstack extends Thread {

private EasyJstackResourceresourceManger;//资源管理类的私有引用,通过此引用可以通过其相关接口对资源进行读写

private int a, b;//将要写入资源的数据

public static void main(String[]args) throws Exception {

EasyJstackResourceresourceManager = new EasyJstackResource();

EasyJstack stack1 = newEasyJstack(resourceManager, 1, 2);

EasyJstack stack2 = newEasyJstack(resourceManager, 3, 4);

stack1.start();

stack2.start();

}

publicEasyJstack(EasyJstackResource resourceManager, int a, int b) {

this.resourceManger =resourceManager;

this.a = a;

this.b = b;

}

public void run() {

while (true) {

this.resourceManger.read();

this.resourceManger.write(this.a,this.b);

}

}

}

package com.jdkTools;

/**

*简单的应用,供测试JDK自带的jstack使用 本应用会造成deadlock,可能会导致系统崩溃

*逻辑:一旦两个线程互相等待的局面出现,死锁(deadlock)就发生了

* @author范芳铭

*/

public class EasyJstackResource {

/**

*管理的两个资源,如果有多个线程并发,那么就会死锁

*/

private Resource resourceA = newResource();

private Resource resourceB = newResource();

public EasyJstackResource() {

this.resourceA.setValue(0);

this.resourceB.setValue(0);

}

public int read() {

synchronized (this.resourceA){

System.out.println(Thread.currentThread().getName()

+ "线程拿到了资源 resourceA的对象锁");

synchronized (resourceB){

System.out.println(Thread.currentThread().getName()

+ "线程拿到了资源 resourceB的对象锁");

return this.resourceA.getValue()+ this.resourceB.getValue();

}

}

}

public void write(int a, int b) {

synchronized (this.resourceB){

System.out.println(Thread.currentThread().getName()

+ "线程拿到了资源 resourceB的对象锁");

synchronized(this.resourceA) {

System.out.println(Thread.currentThread().getName()

+ "线程拿到了资源 resourceA的对象锁");

this.resourceA.setValue(a);

this.resourceB.setValue(b);

}

}

}

public class Resource {

private int value;//资源的属性

public int getValue() {

return value;

}

public void setValue(intvalue) {

this.value = value;

}

}

}

4、运行结果

Thread-0线程拿到了资源 resourceA 的对象锁

Thread-0线程拿到了资源 resourceB 的对象锁

Thread-0线程拿到了资源 resourceB 的对象锁

Thread-1线程拿到了资源 resourceA 的对象锁

应用已经被锁住了

5、用jstack进行分析

C:\Program Files\Java\jdk1.6.0_25\bin>jps -l

5204 com.jdkTools.EasyJstack

6268 sun.tools.jps.Jps

5412

C:\Program Files\Java\jdk1.6.0_25\bin>jstack 5204

2015-01-21 15:32:22

Full thread dump Java HotSpot(TM) Client VM (11.3-b02mixed mode):

…中间省略

"Signal Dispatcher" daemon prio=10tid=0x01a42000 nid=0x1a5c runnable [0x00000000..0x00000000]

java.lang.Thread.State: RUNNABLE

"Finalizer" daemon prio=8 tid=0x01a2b000nid=0x1798 in Object.wait() [0x0bc3f000..0x0bc3fa68]

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

atjava.lang.Object.wait(Native Method)

- waitingon <0x03b50b38> (a java.lang.ref.ReferenceQueue$Lock)

atjava.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:116)

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

atjava.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:132)

atjava.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)

"Reference Handler" daemon prio=10tid=0x01a29c00 nid=0x1e38 in Object.wait() [0x0bbef000..0x0bbefae8]

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

atjava.lang.Object.wait(Native Method)

- waitingon <0x03b50a40> (a java.lang.ref.Reference$Lock)

atjava.lang.Object.wait(Object.java:485)

atjava.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)

- locked<0x03b50a40> (a java.lang.ref.Reference$Lock)

"VM Thread" prio=10 tid=0x01a26800 nid=0x1cecrunnable

"VM Periodic Task Thread" prio=10tid=0x01a80000 nid=0x10e0 waiting on condition

JNI global references: 594

Found one Java-level deadlock:

=============================

"Thread-1":

waiting to lockmonitor 0x01a2dea4 (object 0x03b8ed40, acom.jdkTools.EasyJstackResource$Resource),

which is held by"Thread-0"

"Thread-0":

waiting to lockmonitor 0x01a2eb3c (object 0x03b8ed30, acom.jdkTools.EasyJstackResource$Resource),

which is held by"Thread-1"

Java stack information for the threads listed above:

===================================================

"Thread-1":

atcom.jdkTools.EasyJstackResource.read(EasyJstackResource.java:27)

- waitingto lock <0x03b8ed40> (a com.jdkTools.EasyJstackResource$Resource)

- locked<0x03b8ed30> (a com.jdkTools.EasyJstackResource$Resource)

atcom.jdkTools.EasyJstack.run(EasyJstack.java:34)

"Thread-0":

atcom.jdkTools.EasyJstackResource.write(EasyJstackResource.java:42)

- waitingto lock <0x03b8ed30> (a com.jdkTools.EasyJstackResource$Resource)

- locked<0x03b8ed40> (a com.jdkTools.EasyJstackResource$Resource)

atcom.jdkTools.EasyJstack.run(EasyJstack.java:35)

Found 1 deadlock.

能够明确看到“Found one Java-level deadlock:”能够找到系统中的死锁。

6、分析结果

Java stack information for the threads listed above:

===================================================

"Thread-1":

atcom.jdkTools.EasyJstackResource.read(EasyJstackResource.java:27)

- waitingto lock <0x03b8ed40> (a com.jdkTools.EasyJstackResource$Resource)

- locked<0x03b8ed30> (a com.jdkTools.EasyJstackResource$Resource)

atcom.jdkTools.EasyJstack.run(EasyJstack.java:34)

"Thread-0":

atcom.jdkTools.EasyJstackResource.write(EasyJstackResource.java:42)

- waitingto lock <0x03b8ed30> (a com.jdkTools.EasyJstackResource$Resource)

- locked<0x03b8ed40> (a com.jdkTools.EasyJstackResource$Resource)

atcom.jdkTools.EasyJstack.run(EasyJstack.java:35)

Found 1 deadlock.

仔细看这一段文字,告诉我们 EasyJstackResource.java:27出了状况。如果出现了这种情况,我们就要从这里开始顺藤摸瓜,解决问题。

7、其他状态和简单解读

死锁,Deadlock(重点关注)

执行中,Runnable

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

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

暂停,Suspended

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

阻塞,Blocked(重点关注)

停止,Parked

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值