前面提到用visualvm监控远程主机上的java进程,这种方法的好处是可以“实时”监控,缺点是需要启动jstatd,且只能看到线程总数,无法显示每个线程的详细情况,jstack可以生成某一进程的dump,包含在特定时刻(命令执行时)Java进程内部各个线程的详细情况。
首先用"jps -l"找到目标进程的PID,然后用"jstack [PID]"获得dump,对于大型程序这个dump一般也比较大,所以用"jstack [PID] > dump_file_name"的方法将结果保存在文件dump_file_name里。
下面是dump文件中的一段:
" HSQLDB Timer @5a1b5e32 " daemon prio=3 tid=0x0000000101116800 nid=0x420a in Object.wait() [0xfffffffb5c2ff000] java.lang.Thread.State : TIMED_WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0xfffffffb721e7700> (a org.hsqldb.lib.HsqlTimer\(TaskQueue) at org.hsqldb.lib.HsqlTimer\)TaskQueue.park(HsqlTimer.java:883) - locked <0xfffffffb721e7700> (a org.hsqldb.lib.HsqlTimer\(TaskQueue) at org.hsqldb.lib.HsqlTimer.nextTask(HsqlTimer.java:531) - locked <0xfffffffb721e7700> (a org.hsqldb.lib.HsqlTimer\)TaskQueue) at org.hsqldb.lib.HsqlTimer$TaskRunner.run(HsqlTimer.java:611) at java.lang.Thread.run(Thread.java:662)
以上文本包含的信息包括:
线程名:HSQLDB Timer @5a1b5e32
锁住的资源:<0xfffffffb721e7700>
线程堆栈
线程类型:daemon;
线程优先级(prio):3
线程ID(tid):0x0000000101116800
线程状态:"Object.wait()"和"TIMED_WAITING"
下面的一段供对照:
" T-14319652 " prio=3 tid=0x000000010294d000 nid=0x4208 runnable [0xfffffffb5d5f8000] java.lang.Thread.State: RUNNABLE at org.hsqldb.ExpressionColumn.getValue(ExpressionColumn.java:627) at org.hsqldb.ExpressionLogical.getValue(ExpressionLogical.java:1172) at org.hsqldb.ExpressionLogical.getValue(ExpressionLogical.java:1120) at org.hsqldb.ExpressionLogical.getValue(ExpressionLogical.java:1120) at org.hsqldb.ExpressionLogical.getValue(ExpressionLogical.java:1120)
参考:
Java自带的性能监测工具用法简介——jstack、jconsole、jinfo、jmap、jdb、jsta、jvisualvm