Java程序栈信息文件中的秘密(四)

来源:互联网 发布:先锋软件股份有限公司 编辑:程序博客网 时间:2024/05/16 10:49

如果亲自动手分析Java应用导出的栈信息的话,可以惊讶的发现,原来栈信息中包括了JVM完成自己特定任务的线程栈信息。下面看个例子。

public class Test {    public static void main(final String[] args) throws Exception {        Thread.sleep(200000L);    }}
这是一段非常简单的代码,只有一个线程,并且只做了一件事,那就是睡大觉。为了能够说明问题,在Eclipse中运行这段代码时,增加如下的JVM启动参数,配置如下参数的原因下面会提到。

-XX:+UseConcMarkSweepGC
程序启动后,使用jstack命令导出线程栈的列表,如下。

2013-02-12 01:27:24Full thread dump Java HotSpot(TM) Client VM (23.6-b04 mixed mode):"Service Thread" daemon prio=6 tid=0x17975c00 nid=0x202c runnable [0x00000000]   java.lang.Thread.State: RUNNABLE   Locked ownable synchronizers:- None"C1 CompilerThread0" daemon prio=10 tid=0x17973400 nid=0x25dc waiting on condition [0x00000000]   java.lang.Thread.State: RUNNABLE   Locked ownable synchronizers:- None"Attach Listener" daemon prio=10 tid=0x1796e400 nid=0x1cf0 waiting on condition [0x00000000]   java.lang.Thread.State: RUNNABLE   Locked ownable synchronizers:- None"Signal Dispatcher" daemon prio=10 tid=0x1796cc00 nid=0x1d3c runnable [0x00000000]   java.lang.Thread.State: RUNNABLE   Locked ownable synchronizers:- None"Surrogate Locker Thread (Concurrent GC)" daemon prio=6 tid=0x1796b400 nid=0x21ec waiting on condition [0x00000000]   java.lang.Thread.State: RUNNABLE   Locked ownable synchronizers:- None"Finalizer" daemon prio=8 tid=0x17921800 nid=0x2618 in Object.wait() [0x177df000]   java.lang.Thread.State: WAITING (on object monitor)at java.lang.Object.wait(Native Method)- waiting on <0x02be56a0> (a java.lang.ref.ReferenceQueue$Lock)at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:135)- locked <0x02be56a0> (a java.lang.ref.ReferenceQueue$Lock)at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:151)at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:177)   Locked ownable synchronizers:- None"Reference Handler" daemon prio=10 tid=0x02b3e400 nid=0x2304 in Object.wait() [0x1778f000]   java.lang.Thread.State: WAITING (on object monitor)at java.lang.Object.wait(Native Method)- waiting on <0x02be5278> (a java.lang.ref.Reference$Lock)at java.lang.Object.wait(Object.java:503)at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133)- locked <0x02be5278> (a java.lang.ref.Reference$Lock)   Locked ownable synchronizers:- None"main" prio=6 tid=0x00868c00 nid=0x1dc waiting on condition [0x0098f000]   java.lang.Thread.State: TIMED_WAITING (sleeping)at java.lang.Thread.sleep(Native Method)at DeadLock.main(DeadLock.java:3)   Locked ownable synchronizers:- None"VM Thread" prio=10 tid=0x02b38800 nid=0x195c runnable "Gang worker#0 (Parallel GC Threads)" prio=10 tid=0x0086c800 nid=0x2780 runnable "Gang worker#1 (Parallel GC Threads)" prio=10 tid=0x02a40c00 nid=0x25a0 runnable "Concurrent Mark-Sweep GC Thread" prio=10 tid=0x02ab6000 nid=0x1828 runnable "VM Periodic Task Thread" prio=10 tid=0x17989c00 nid=0x20b0 waiting on condition JNI global references: 115
是不是非常壮观,这么简单的代码在JVM内部运行时,居然需要生成这么多的线程。另外在文件的尾部,还可以看到CMS垃圾回收器的线程,是不是很有意思?这也是上面增加相关参数的原因。

这里举这个例子只是想说明通过分析Java应用导出的栈信息文件是一种很有效的窥视JVM内部实现的方法,至于能窥视到多少信息,就要看各人的实力了。本人才疏学浅,暂时还看不出什么特别的东东,目前只能看出JVM自动生成了哪些线程,至于各个线程的作用,除了垃圾回收器相关的,其它线程的功能暂时还不清楚,留待以后找到资料再说。

曾经在工作中借助top之类的命令来定位Java应用占用CPU过高的问题时,偶然发现过执行垃圾回收任务的线程占用很高CPU的情况,不过问题的根本原因和JVM倒没有什么关系。

原创粉丝点击