虚拟机学习系列 - 6 - JDK工具

来源:互联网 发布:销售网络分布图下载 编辑:程序博客网 时间:2024/05/22 00:42

目录

虚拟机学习系列 - 1 - 运行时数据区域 
虚拟机学习系列 - 2 - 垃圾收集概述 
虚拟机学习系列 - 3 - 垃圾收集算法 
虚拟机学习系列 - 4 - 垃圾收集器 
虚拟机学习系列 - 5 - 内存分配与回收策略

虚拟机学习系列 - 6 - JDK工具

虚拟机学习系列 - 附 - 虚拟机参数

虚拟机学习系列 - 附 - OQL(对象查询语言) 


JDK命令行工具

简单介绍下面6个

1.jps(JVM Process Status Tool)

2.jstat(JVM Statistics Monitoring Tool)

3.jinfo(Configuration Info for Java)

4.jmap(Memory Map for Java)

5.jhat(JVM Heap Dump Browser)

6.jstack(Stack Trace for Java)



1.jps

    主要功能:可以列出正在运行的虚拟机进程

                 显示虚拟机执行主类(main函数所在的类)

                 这些进程的本地虚拟机唯一ID

    部分选项:-q:只输出LVMID,省略主类的名称

                 -m:输出虚拟机进程启动时传给主类main()函数的参数

                 -l:输出主类的全类名,如果进程执行的是Jar包,输出Jar路径

                 -v:输出虚拟机进程启动时JVM参数

    命令格式:jps [option] [hostid]

    示例:

C:\Program Files\Java\jdk1.6.0_30\bin>jps -v
3972 Jps -Dapplication.home=C:\Program Files\Java\jdk1.6.0_30 -Xms8m
6012  -Xms128m -Xmx512m -XX:MaxPermSize=256m -Dosgi.requiredJavaVersion=1.5 -Dosgi.instance.area=@user.home/Applica
sgi.configuration.area=@user.home/Application Data/XMind/configuration-cathy
692  -Dosgi.requiredJavaVersion=1.5 -Xms512m -Xmx512m -Xmn256m -Xverify=none -XX:PermSize=96m -XX:MaxPermSize=256m


2.jstat

    主要功能:可以显示本地或远程虚拟机进程中类装载、内存、垃圾收集、JIT编译等运行数据(显示远程虚拟机信息需要远程主机提供RMI支持)

    部分选项:-class:监视类装载、卸载数量、总空间及类装载所耗费的时间

                 -gc:监听Java堆状况,包括Eden区、两个Survivor区、老年代、永久代等的容量,以用空间、GC时间合计等信息

                 -gccapacity:监视内容与-gc基本相同,但输出主要关注java堆各个区域使用到的最大和最小空间

                 -gcutil:监视内容与-gc基本相同,但输出主要关注已使用空间占总空间的百分比

                 -gccause:与-gcutil功能一样,但是会额外输出导致上一次GC产生的原因

                 -gcnew:监视新生代GC状况

                 -gcnewcapacity:监视内同与-gcnew基本相同,输出主要关注使用到的最大和最小空间

                 -gcold:监视老年代GC情况

                 -gcoldcapacity:监视内同与-gcold基本相同,输出主要关注使用到的最大和最小空间

                 -gcpermcapacity:输出永久代使用到最大和最小空间

                 -compiler:输出JIT编译器编译过的方法、耗时等信息

                 -printcompilation:输出已经被JIT编译的方法

    命令格式:jstat [option vmid [interval[s|ms] [count]] ]

                 对命令格式中VMID和LVMID特别说明:如果是本地虚拟机进程,VMID和LVMID是一致的,如果是远程虚拟机进程,那么VMID格式是:[protocol:][//]lvmid[@hostname[:port]/servername],如果省略interval和count,则只查询一次

    示例:

C:\Program Files\Java\jdk1.6.0_30\bin>jstat -gc 6012 500 5
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       PC     PU    YGC     YGCT    FGC    FGCT     GCT
4352.0 4352.0  0.0    66.8  35072.0  33768.3   87424.0    72125.8   24320.0 24313.0     47    0.600   2      0.272    0.871
4352.0 4352.0  0.0    66.8  35072.0  33768.3   87424.0    72125.8   24320.0 24313.0     47    0.600   2      0.272    0.871
4352.0 4352.0  0.0    66.8  35072.0  33768.3   87424.0    72125.8   24320.0 24313.0     47    0.600   2      0.272    0.871
4352.0 4352.0  0.0    66.8  35072.0  33768.3   87424.0    72125.8   24320.0 24313.0     47    0.600   2      0.272    0.871
4352.0 4352.0  0.0    66.8  35072.0  33768.3   87424.0    72125.8   24320.0 24313.0     47    0.600   2      0.272    0.871

查询进程6012垃圾收集情况:0.5秒一次共五次


3.jinfo

    主要功能:实时查看和调整虚拟机的各项参数(可以显示未被显示指定的参数的系统默认值,不少功能在windows受限)

    部分选项:-flag:显示未被显示指定的参数的系统默认值

                 -sysprops:打印虚拟机进程的System.getProperties(),可以使用-flag [+|-]name或-flag name=value修改部分参数

    命令格式:jinfo [option] pid

    示例:

C:\Program Files\Java\jdk1.6.0_30\bin>jinfo -flag SurvivorRatio 6012
-XX:SurvivorRatio=8




4.jmap

    主要功能:获取堆转储快照

                 查询finalize执行队列

                 查询java堆和永久代的详细信息(如空间使用率、当前使用的收集器)

    部分选项:-dump:生成java堆转储快照

                 -finalizerinfo:显示在F-Queue中等待Finalizer线程执行finalize方法的对象(只在Linux/Solaris下有效)

                 -heap:显示java堆详细信息(只在Linux/Solaris下有效)

                 -histo:显示堆中对象统计信息

                 -permstat:以ClassLoader为统计口径显示永久代内存状态(只在Linux/Solaris下有效)

                 -F:当虚拟机进程对-dump选项没有响应时,可使用这个选项强制生成dump快照(只在Linux/Solaris下有效)

    命令格式:jmap [option] vmid

    示例:

C:\Program Files\Java\jdk1.6.0_30\bin>jmap -dump:format=b,file=d:xmind.hprof 6012
Dumping heap to D:\xmind.hprof ...
Heap dump file created


5.jhat

    主要功能:jhat,用于分析heap dump文件(用mat代替此工具)



6jstack

    主要功能:生成虚拟机的线程快照,threaddump或javacore文件(线程快照是虚拟机每一条线程正在执行的方法,目的是定位线程出现长时间停顿的原因)

    部分选项:-F:当正常输出的请求不被响应时,强制输出线程堆栈

                 -l:除堆栈外,显示关于锁的附加信息

                 -m:如果调用到本地方法的话,可以显示C/C++的堆栈

    命令格式:jstack [option] vmid

    示例:

C:\Program Files\Java\jdk1.6.0_30\bin>jstack -l 6012
2012-05-13 11:57:35
Full thread dump Java HotSpot(TM) Client VM (20.5-b03 mixed mode, sharing):

"Java2D Disposer" daemon prio=10 tid=0x39cc9c00 nid=0x146c in Object.wait() [0x079af000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x12f94a08> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(Unknown Source)
        - locked <0x12f94a08> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(Unknown Source)
        at sun.java2d.Disposer.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)

   Locked ownable synchronizers:
        - None

"XMind: Auto Save Temporary Workbooks" daemon prio=2 tid=0x05610400 nid=0xaf8 waiting on condition [0x0758f000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(Native Method)
        at org.xmind.ui.internal.editor.WorkbookRefManager$AutoHibernateJob.run(WorkbookRefManager.java:221)
        at java.lang.Thread.run(Unknown Source)

   Locked ownable synchronizers:
        - None

"Worker-2" prio=6 tid=0x055c8000 nid=0x14cc in Object.wait() [0x073bf000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x1291e468> (a org.eclipse.core.internal.jobs.WorkerPool)
        at org.eclipse.core.internal.jobs.WorkerPool.sleep(WorkerPool.java:185)
        - locked <0x1291e468> (a org.eclipse.core.internal.jobs.WorkerPool)
        at org.eclipse.core.internal.jobs.WorkerPool.startJob(WorkerPool.java:217)
        at org.eclipse.core.internal.jobs.Worker.run(Worker.java:51)

   Locked ownable synchronizers:
        - None

……




JDK可视化工具

1.JConsole(Java Monitoring and Management Console)

2.VisualVM(All-in-One Java Toubleshooting Tool)



内存页


线程页

下面是书中几个示例(线程死循环,线程锁等待)

public static void createBusyThread(){new Thread("testBusyThread"){public void run(){while(true);//11行}}.start();}public static void createLockThread(final Object lock){new Thread("testLockThread"){public void run(){synchronized (lock) {try {lock.wait();//21行} catch (InterruptedException e) {e.printStackTrace();}}}}.start();}public static void main(String[] args) throws IOException {BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));bufferedReader.readLine();//32行Main.createBusyThread();bufferedReader.readLine();Main.createLockThread(new Object());}

 在线程页中查看


 堆栈追踪: 
java.io.FileInputStream.readBytes(Native Method)
java.io.FileInputStream.read(Unknown Source)
java.io.BufferedInputStream.read1(Unknown Source)
java.io.BufferedInputStream.read(Unknown Source)
   - 已锁定 java.io.BufferedInputStream@1c293f8
sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
sun.nio.cs.StreamDecoder.implRead(Unknown Source)
sun.nio.cs.StreamDecoder.read(Unknown Source)
   - 已锁定 java.io.InputStreamReader@180a8b7
java.io.InputStreamReader.read(Unknown Source)
java.io.BufferedReader.fill(Unknown Source)
java.io.BufferedReader.readLine(Unknown Source)
   - 已锁定 java.io.InputStreamReader@180a8b7
java.io.BufferedReader.readLine(Unknown Source)
jvmTest.Main.main(Main.java:32)


运行过bufferedReader.readLine();之后可以看到testBusyThread的信息,现在右侧选中线程testBusyThread

名称: testBusyThread
状态: RUNNABLE
阻塞总数:0  等待总数: 0
 


堆栈追踪: 
jvmTest.Main$1.run(Main.java:11)


testLockThread也一样

名称: testLockThread
状态:WAITING 在 java.lang.Object@1921360 上 
阻塞总数:0  等待总数: 1 


堆栈追踪: 
java.lang.Object.wait(Native Method)
java.lang.Object.wait(Object.java:485)
jvmTest.Main$2.run(Main.java:21)


死锁的测试我们用多线程学习系列 - 1 - Single Threaded Execution Pattern 中的代码来测试吧

public class ThreadTest {public static class Tool{private final String name;public Tool(String name){this.name = name;}public String toString(){return "[" + name + "]";}}public static class EaterThread extends Thread{private String name;private Tool leftHand;private Tool rightHand;public EaterThread(String name, Tool leftHand, Tool rightHand){super(name);this.name = name;this.leftHand = leftHand;this.rightHand = rightHand;}public void run(){while(true){eat();//30行}}public void eat(){synchronized (leftHand) {System.out.println(name + " takes up " + leftHand + "(left.)");synchronized (rightHand) {System.out.println(name + " takes up " + rightHand + "(right.)");System.out.println(name + " is eating now ,yam yam!");System.out.println(name + " put down " + rightHand + "(right.)");}System.out.println(name + " put down " + leftHand + "(left.)");}}}public static void main(String[] args) {    Tool spoon = new Tool("Spoon");    Tool fork = new Tool("Fork");    new EaterThread("Alice", spoon, fork).start();    new EaterThread("Bobby", fork, spoon).start();}}

 结果如下

名称: Alice
状态:BLOCKED 在 ThreadTest$Tool@1f31652 上,拥有者: Bobby
阻塞总数:1  等待总数: 0
 


堆栈追踪: 
ThreadTest$EaterThread.eat(ThreadTest.java:38)
   - 已锁定 ThreadTest$Tool@778255
ThreadTest$EaterThread.run(ThreadTest.java:30)

Bobby 的结果就不再列出了


就不再总结了




转贴请保留以下链接

本人blog地址

http://su1216.iteye.com/

http://blog.csdn.net/su1216/

原创粉丝点击