没有合适的资源?快使用搜索试试~ 我知道了~
JStack和Java Thread Dumps分析
需积分: 37 8 下载量 176 浏览量
2016-03-14
14:15:10
上传
评论 1
收藏 692KB PDF 举报
温馨提示
试读
17页
JStack和Java Thread Dumps分析
资源推荐
资源详情
资源评论
JStack 和 Java Thread Dumps 分析
1
JStack 和 Java Thread Dumps 分析
任喜军
Java 程序员总是非常幸运地有 Sun 公司给力的工具 jstack 帮你 Dump 当前所有 Java 线程的
运行堆栈(jstack 工具在你的 JDK 安装目录的 bin/ 里面可以看到)
Jstack 用法帮助
jstack --help
Usage:
jstack [-l] <pid>
(to connect to running process)
jstack -F [-m] [-l] <pid>
(to connect to a hung process)
jstack [-m] [-l] <executable> <core>
(to connect to a core file)
jstack [-m] [-l] [server_id@]<remote server IP or hostname>
(to connect to a remote debug server)
Options:
-F to force a thread dump. Use when jstack <pid> does not respond
(process is hung)
-m to print both java and native frames (mixed mode)
-l long listing. Prints additional information about locks
-h or -help to print this help message
其中 pid (Java 进程的 id 号,你可以通过 JDK/bin/jps 工具来获取你的机器上所有正在
运行的 java 进程 id)是必要的参数。
-l:输出 locks 相关的信息。
jstack –l 2345 >stack.log //表示将 java 进程号为 2345 的堆栈转存到文件 stack.log
中。
可以使用 JDK 自带的工具:jps 来查看所有运行的 Java 进程号
jps 用法:
$ jps -help
usage: jps [-help]
jps [-q] [-mlvV] [<hostid>]
Definitions:
<hostid>: <hostname>[:<port>]
接下来就是分析这个 stack.log 文件,帮你发现你的程序都在干什么、以及有哪些锁竞争激烈。
查看锁竞争
简单案例,MyThread.java 的代码清单:
JStack 和 Java Thread Dumps 分析
2
1 public class MyThread implements Runnable{
2
3 public void run() {
4 synchronized(this) {
5 for (int i = 1; i < 10000000; i--) {
6
System.out.println(Thread.currentThread().getName() + " synchronized
loop " + i);
7 if( i % 10000 == 0){
8 try{
9 this.notifyAll();
10 this.wait(1000);}
11 catch(Exception e){
12 e.printStackTrace();
13 }
14 }
15 }
16 }
17 }
18 public static void main(String[] args) {
19 MyThread t1 = new MyThread();
20 Thread ta = new Thread(t1, "A");
21 Thread tb = new Thread(t1, "B");
22 Thread tc = new Thread(t1, "C");
23 ta.start();
24 tb.start();
25 tc.start();
26 }
27 }
将这段代码运行起来,然后用 Jstack 命令不停地去抓取 Stack,就会得到这样的结果:
16 "C" prio=10 tid=0x00007f342809d000 nid=0x2606 in Object.wait()
[0x00007f342e1a2000]
17 java.lang.Thread.State: TIMED_WAITING (on object monitor)
18 at java.lang.Object.wait(Native Method)
19 - waiting on <0x00000000c2002180> (a MyThread)
20 at MyThread.run(MyThread.java:10)
21 - locked <0x00000000c2002180> (a MyThread)
22 at java.lang.Thread.run(Thread.java:679)
23
24 "B" prio=10 tid=0x00007f342809b000 nid=0x2605 in Object.wait()
[0x00007f342e2a3000]
25 java.lang.Thread.State: BLOCKED (on object monitor)
26 at java.lang.Object.wait(Native Method)
27 - waiting on <0x00000000c2002180> (a MyThread)
28 at MyThread.run(MyThread.java:10)
29 - locked <0x00000000c2002180> (a MyThread)
30 at java.lang.Thread.run(Thread.java:679)
31
JStack 和 Java Thread Dumps 分析
3
32 "A" prio=10 tid=0x00007f3428099000 nid=0x2604 runnable
[0x00007f342e3a4000]
33 java.lang.Thread.State: RUNNABLE
34 at java.io.FileOutputStream.writeBytes(Native Method)
35 at
java.io.FileOutputStream.write(FileOutputStream.java:297)
36 at
java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
37 at
java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
38 - locked <0x00000000c2002868> (a
java.io.BufferedOutputStream)
39 at java.io.PrintStream.write(PrintStream.java:449)
40 - locked <0x00000000c2002280> (a java.io.PrintStream)
41 at
sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:220)
42 at
sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:290)
43 at
sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:103)
44 - locked <0x00000000c2002970> (a
java.io.OutputStreamWriter)
45 at
java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:185)
46 at java.io.PrintStream.newLine(PrintStream.java:513)
47 - locked <0x00000000c2002280> (a java.io.PrintStream)
48 at java.io.PrintStream.println(PrintStream.java:774)
49 - locked <0x00000000c2002280> (a java.io.PrintStream)
50 at MyThread.run(MyThread.java:6)
51 - locked <0x00000000c2002180> (a MyThread)
52 at java.lang.Thread.run(Thread.java:679)
每一段都表示一个线程调用栈,如这一行:
"A" prio=10 tid=0x00007f3428099000 nid=0x2604 runnable
[0x00007f342e3a4000]
"A" : 该线程名字,建议大家创建线程的时候给定一个名字,便于定位
nid=0x2604: 该线程的线程号是 16 进制的 2604
runnable : 该线程当前的状态,这个很重要
接下来的这一行是对线程状态的详细说明:
java.lang.Thread.State: RUNNABLE
这一个线程(线程号:2604)的调用栈从下往上读,从 at
java.lang.Thread.run(Thread.java:679) 开始调用 MyThread.java 的第 6 行:
6
System.out.println(Thread.currentThread().getName() + " synchr
onized loop " + i);
JStack 和 Java Thread Dumps 分析
4
说明该线程进入到了 synchronized 代码块里面,抢到了 this 这个锁。这也意味着所有其他
线程都得等待,没法执行 synchronized 代码块,也就是我们可以看到线程 A :
51 - locked <0x00000000c2002180> (a MyThread)
线程 B :
25 java.lang.Thread.State: BLOCKED (on object monitor)
27 - waiting on <0x00000000c2002180> (a MyThread)
线程 C :
17 java.lang.Thread.State: TIMED_WAITING (on object monitor)
19 - waiting on <0x00000000c2002180> (a MyThread)
很明显线程 A 抢到了锁 0x00000000c2002180(this)同时线程 B/C 只能是
BLOCKED 和 TIMED_WAITIN 状态。
而这里的线程 B 是 BLOCKED 状态,意味着线程 B 尝试去获取 this 锁,但是没成功,所以被
blocked 了;而线程 C 是 TIMED_WAITING 状态意味着线程 C 是主动代用第 10 行代码:
10 this.wait(1000);}
进入等待状态的,并且带有 1000ms 的 timeout 时间,也就是 C 线程在 wait 1000ms 后将主
动尝试获取 this 锁,也就是执行这行代码:
4 synchronized(this) {
当然这个 1000ms 这中间没有其它线程调用第 9 行代码:
9 this.notifyAll();
如果反复执行 jstack 去抓取线程状态的话会发现 A B C 三个线程状态这 RUNNABLE
BLOCKED TIMED_WAITING 轮转,这也是我们这段代码的目的。通过 MyThread.java 这段简
单的代码和线程调用栈来分析,我们得到了一些基本的认识,让我们回到所有其它课本给我们讲
解的这些东西:
剩余16页未读,继续阅读
资源评论
onyas
- 粉丝: 466
- 资源: 36
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- Screenshot_20240427_031602.jpg
- 网页PDF_2024年04月26日 23-46-14_QQ浏览器网页保存_QQ浏览器转格式(6).docx
- 直接插入排序,冒泡排序,直接选择排序.zip
- 在排序2的基础上,再次对快排进行优化,其次增加快排非递归,归并排序,归并排序非递归版.zip
- 实现了7种排序算法.三种复杂度排序.三种nlogn复杂度排序(堆排序,归并排序,快速排序)一种线性复杂度的排序.zip
- 冒泡排序 直接选择排序 直接插入排序 随机快速排序 归并排序 堆排序.zip
- 课设-内部排序算法比较 包括冒泡排序、直接插入排序、简单选择排序、快速排序、希尔排序、归并排序和堆排序.zip
- Python排序算法.zip
- C语言实现直接插入排序、希尔排序、选择排序、冒泡排序、堆排序、快速排序、归并排序、计数排序,并带图详解.zip
- 常用工具集参考用于图像等数据处理
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功