JDK的很多小工具的名字都参考了Unix命令的命名方式,jps(JVM Process Status Tool)是其中的典型。功能是可以列出正在运行的虚拟机进程,并显示虚拟机执行主类(Main Class,main()函数所在的类)名称以及这些进程的本地虚拟机唯一ID(Local Virtual Machine Identifier,LVMID)。
jinfo(Configuration Info for Java)的作用是实时地查看和调整虚拟机各项参数。使用jps命令的-v参数可以查看虚拟机启动时显式指定的参数列表,但如果想指定未被显式指定的参数的系统默认值,就可以使用jinfo的-flag选项进行查询,jinfo还可以使用-sysprops选项把虚拟机进程的System.getProperties()的内容打印出来。
jinfo的命令格式:
jinfo [ option ] pid
jmap: Java内存映像工具
jmap(Memory Map for Java)命令用于生成堆转储快照(一般称为dump或是heapdump文件)。如果不使用jmap命令,要想获取Java堆转储快照,可以使用
C:\Program Files\Java\jdk1.8.0_171\bin>jmap -dump:format=b,file=D:\dump.hprof 8812 Dumping heap to D:\dump.hprof ... Heap dump file created
jhat: 虚拟机堆转储快照分析工具
Sun JDK提供jhat(JVM Heap Analysis Tool)命令与jmap搭配使用,来分析jmap生成的堆转储快照。jhat内置了一个微型的HTTP/HTML服务器,生成的dump文件的分析结果后,可以在浏览器中查看。一般不建议使用。可以使用其他工具分析,比如Eclipse Memory Analyzer、IBM HeapAnalyzer或JProfiler等工具,都可以实现更强大更专业的分析功能。
1 2 3 4 5 6 7 8 9 10
C:\Program Files\Java\jdk1.8.0_171\bin>jhat d:\dump.hprof Reading from d:\dump.hprof... Dump file created Thu Aug 20 21:22:50 CST 2020 Snapshot read, resolving... Resolving 617466 objects... Chasing references, expect 123 dots........................................................................................................................... Eliminating duplicate references........................................................................................................................... Snapshot resolved. Started HTTP server on port 7000 Server is ready.
在浏览器输入http://localhost:7000即可查看分析结果。
jstack :Java堆栈跟踪工具
jstack(Stack Trace for Java)命令用于生成虚拟机当前时刻的线程快照(一般称为threaddump或者javacore文件)。线程快照就是当前虚拟机内每一条线程正在执行的方法堆栈集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等等都是导致线程长时间停顿的原因。线程出现停顿的时候通过jstack来查看各线程的调用堆栈,就可以知道没有响应的现场到底在后台做些什么事情,或者等待什么资源。
"main" #1 prio=5 os_prio=0 cpu=484.38ms elapsed=1227.43s tid=0x0000022da3b28000 nid=0x1ec0 in Object.wait() [0x000000e64f7ff000] java.lang.Thread.State: TIMED_WAITING (on object monitor) at java.lang.Object.wait(java.base@11.0.6/Native Method) - waiting on <0x00000000d00e2010> (a java.lang.Object) at com.intellij.execution.rmi.RemoteServer.start(RemoteServer.java:91) - waiting to re-lock in wait() <0x00000000d00e2010> (a java.lang.Object) at org.jetbrains.idea.maven.server.RemoteMavenServer36.main(RemoteMavenServer36.java:23)
"Reference Handler" #2 daemon prio=10 os_prio=2 cpu=0.00ms elapsed=1227.39s tid=0x0000022dbcc65800 nid=0x29e8 waiting on condition [0x000000e64feff000] java.lang.Thread.State: RUNNABLE at java.lang.ref.Reference.waitForReferencePendingList(java.base@11.0.6/Native Method) at java.lang.ref.Reference.processPendingReferences(java.base@11.0.6/Reference.java:241) at java.lang.ref.Reference$ReferenceHandler.run(java.base@11.0.6/Reference.java:213)
"Finalizer" #3 daemon prio=8 os_prio=1 cpu=0.00ms elapsed=1227.39s tid=0x0000022dbcc67000 nid=0x3158 in Object.wait() [0x000000e64fffe000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(java.base@11.0.6/Native Method) - waiting on <0x00000000d00e23c0> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(java.base@11.0.6/ReferenceQueue.java:155) - waiting to re-lock in wait() <0x00000000d00e23c0> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(java.base@11.0.6/ReferenceQueue.java:176) at java.lang.ref.Finalizer$FinalizerThread.run(java.base@11.0.6/Finalizer.java:170)
"Common-Cleaner" #11 daemon prio=8 os_prio=1 cpu=0.00ms elapsed=1227.33s tid=0x0000022dbd5ea800 nid=0x488 in Object.wait() [0x000000e6507fe000] java.lang.Thread.State: TIMED_WAITING (on object monitor) at java.lang.Object.wait(java.base@11.0.6/Native Method) - waiting on <0x00000000d01a1f98> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(java.base@11.0.6/ReferenceQueue.java:155) - waiting to re-lock in wait() <0x00000000d01a1f98> (a java.lang.ref.ReferenceQueue$Lock) at jdk.internal.ref.CleanerImpl.run(java.base@11.0.6/CleanerImpl.java:148) at java.lang.Thread.run(java.base@11.0.6/Thread.java:834) at jdk.internal.misc.InnocuousThread.run(java.base@11.0.6/InnocuousThread.java:134) // ................. "RMI TCP Connection(idle)" #27 daemon prio=5 os_prio=0 cpu=0.00ms elapsed=24.77s tid=0x0000022dbf12f000 nid=0x1724 waiting on condition [0x000000e64f5fe000] java.lang.Thread.State: TIMED_WAITING (parking) at jdk.internal.misc.Unsafe.park(java.base@11.0.6/Native Method) - parking to wait for <0x00000000d00b9568> (a java.util.concurrent.SynchronousQueue$TransferStack) at java.util.concurrent.locks.LockSupport.parkNanos(java.base@11.0.6/LockSupport.java:234) at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(java.base@11.0.6/SynchronousQueue.java:462) at java.util.concurrent.SynchronousQueue$TransferStack.transfer(java.base@11.0.6/SynchronousQueue.java:361) at java.util.concurrent.SynchronousQueue.poll(java.base@11.0.6/SynchronousQueue.java:937) at java.util.concurrent.ThreadPoolExecutor.getTask(java.base@11.0.6/ThreadPoolExecutor.java:1053) at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@11.0.6/ThreadPoolExecutor.java:1114) at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@11.0.6/ThreadPoolExecutor.java:628) at java.lang.Thread.run(java.base@11.0.6/Thread.java:834)