JVM相关命令解释

843 阅读5分钟

jps

显示当前所有java进程pid的命令,我们可以通过这个命令来查看到底启动了几个java进程(因为每个java程序都会独占一个java虚拟机实例),不过jps有个缺点是只显示当前用户的进程id,要显示其它用户的还是只能用linux的ps命令。

常用

jps -l:输出应用程序main.class的完整package名或者应用程序jar文件完整路径名 image.png

jps -v:输出传递给JVM的参数 image.png

jps失效

我们在定位问题过程会遇到这样一种情况,用jps查看不到进程id,用ps -ef|grep java却能看到启动的java进程。要解释这种现象,先来了解下jps的实现机制:
java程序启动后,会在目录/tmp/hsperfdata_{userName}/下生成几个文件,文件名就是java进程的pid,因此jps列出进程id就是把这个目录下的文件名列一下而已,至于系统参数,则是读取文件中的内容。

如果jps命令失效,可以使用linux的命令获取java进程id

jstack

主要用于生成指定进程当前时刻的线程快照,线程快照是当前java虚拟机每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是用于定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致长时间等待。

用法

image.png

常用

jstack <pid> 输出结果

2021-07-22 15:02:19
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.291-b10 mixed mode):

"parallel-3" #26 daemon prio=5 os_prio=0 tid=0x000001c3f6788800 nid=0x4cb8 waiting on condition [0x000000bc1a6fe000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000f2ca0c48> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(Unknown Source)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(Unknown Source)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(Unknown Source)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor.getTask(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)

"elastic-evictor-1" #24 daemon prio=5 os_prio=0 tid=0x000001c3f8303800 nid=0x4470 waiting on condition [0x000000bc1c7ff000]
   java.lang.Thread.State: TIMED_WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000edee01f8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.parkNanos(Unknown Source)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(Unknown Source)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(Unknown Source)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor.getTask(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)

"parallel-2" #23 daemon prio=5 os_prio=0 tid=0x000001c3f9d65800 nid=0x3f74 waiting on condition [0x000000bc1c4ff000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000f2ca0de8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(Unknown Source)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(Unknown Source)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(Unknown Source)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor.getTask(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)

"pool-2-thread-1" #22 prio=5 os_prio=0 tid=0x000001c3f94db000 nid=0x1ba4 waiting on condition [0x000000bc1c3ff000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000f2c92ac0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(Unknown Source)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(Unknown Source)
        at java.util.concurrent.LinkedBlockingQueue.take(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor.getTask(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)

"Reconciler-1" #21 daemon prio=5 os_prio=0 tid=0x000001c3f94cc800 nid=0x3c20 waiting on condition [0x000000bc1c2fe000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000c00af268> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(Unknown Source)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(Unknown Source)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(Unknown Source)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor.getTask(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)

"parallel-1" #20 daemon prio=5 os_prio=0 tid=0x000001c3f94aa800 nid=0x51e0 waiting on condition [0x000000bc1c1fe000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000f2ca11d8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(Unknown Source)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(Unknown Source)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(Unknown Source)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor.getTask(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)

"pool-5-thread-1" #19 prio=5 os_prio=0 tid=0x000001c3f9473000 nid=0x4d0c waiting on condition [0x000000bc1c0fe000]
   java.lang.Thread.State: TIMED_WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000f2d7b7f8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.parkNanos(Unknown Source)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(Unknown Source)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(Unknown Source)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor.getTask(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)

"pool-4-thread-1" #18 prio=5 os_prio=0 tid=0x000001c3f943b000 nid=0x5378 runnable [0x000000bc1bffe000]
   java.lang.Thread.State: RUNNABLE
        at java.io.FileInputStream.readBytes(Native Method)
        at java.io.FileInputStream.read(Unknown Source)
        at java.io.BufferedInputStream.fill(Unknown Source)
        at java.io.BufferedInputStream.read(Unknown Source)
        - locked <0x00000000c005af80> (a java.io.BufferedInputStream)
        at org.eclipse.lsp4j.jsonrpc.json.StreamMessageProducer.listen(StreamMessageProducer.java:79)
        at org.eclipse.lsp4j.jsonrpc.json.ConcurrentMessageProcessor.run(ConcurrentMessageProcessor.java:113)
        at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
        at java.util.concurrent.FutureTask.run(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)

"DestroyJavaVM" #17 prio=5 os_prio=0 tid=0x000001c3e1e6e000 nid=0x4c7c waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"LanguageServerApp-lifecycle" #16 prio=5 os_prio=0 tid=0x000001c3f7ba0000 nid=0x5320 waiting on condition [0x000000bc1befe000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000f2d7c200> (a java.util.concurrent.FutureTask)
        at java.util.concurrent.locks.LockSupport.park(Unknown Source)
        at java.util.concurrent.FutureTask.awaitDone(Unknown Source)
        at java.util.concurrent.FutureTask.get(Unknown Source)
        at org.eclipse.lsp4j.jsonrpc.json.ConcurrentMessageProcessor$1.get(ConcurrentMessageProcessor.java:54)
        at org.eclipse.lsp4j.jsonrpc.json.ConcurrentMessageProcessor$1.get(ConcurrentMessageProcessor.java:50)
        at org.springframework.ide.vscode.commons.languageserver.LanguageServerRunner.startAsClient(LanguageServerRunner.java:138)
        at org.springframework.ide.vscode.commons.languageserver.LanguageServerRunner.start(LanguageServerRunner.java:93)
        at org.springframework.ide.vscode.commons.languageserver.LanguageServerRunner.lambda$run$0(LanguageServerRunner.java:63)
        at org.springframework.ide.vscode.commons.languageserver.LanguageServerRunner$$Lambda$305/1313799195.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)

"Simple-Language-Server main thread" #14 daemon prio=5 os_prio=0 tid=0x000001c3f9305800 nid=0x3520 waiting on condition [0x000000bc1bdfe000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000c0365c98> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(Unknown Source)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(Unknown Source)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(Unknown Source)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor.getTask(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)

"Service Thread" #10 daemon prio=9 os_prio=0 tid=0x000001c3f7a1e800 nid=0x1854 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C1 CompilerThread3" #9 daemon prio=9 os_prio=2 tid=0x000001c3f6784000 nid=0x3544 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread2" #8 daemon prio=9 os_prio=2 tid=0x000001c3f6777000 nid=0x4ce4 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread1" #7 daemon prio=9 os_prio=2 tid=0x000001c3f6775000 nid=0x1bec waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" #6 daemon prio=9 os_prio=2 tid=0x000001c3f6772800 nid=0x18a0 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x000001c3f676e000 nid=0x6c waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x000001c3f676d800 nid=0x52bc runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Finalizer" #3 daemon prio=8 os_prio=1 tid=0x000001c3f66f3800 nid=0x4864 in Object.wait() [0x000000bc1b4fe000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x00000000c0029d58> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(Unknown Source)
        - locked <0x00000000c0029d58> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(Unknown Source)
        at java.lang.ref.Finalizer$FinalizerThread.run(Unknown Source)

"Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x000001c3f66cb800 nid=0x3c6c in Object.wait() [0x000000bc1b3fe000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x00000000c0031778> (a java.lang.ref.Reference$Lock)
        at java.lang.Object.wait(Unknown Source)
        at java.lang.ref.Reference.tryHandlePending(Unknown Source)
        - locked <0x00000000c0031778> (a java.lang.ref.Reference$Lock)
        at java.lang.ref.Reference$ReferenceHandler.run(Unknown Source)

"VM Thread" os_prio=2 tid=0x000001c3f66c0800 nid=0x48e0 runnable

"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x000001c3e1e84000 nid=0x30dc runnable

"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x000001c3e1e85800 nid=0x50a4 runnable

"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x000001c3e1e86800 nid=0x41a8 runnable

"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x000001c3e1e89000 nid=0x1310 runnable

"GC task thread#4 (ParallelGC)" os_prio=0 tid=0x000001c3e1e8a000 nid=0x53d0 runnable

"GC task thread#5 (ParallelGC)" os_prio=0 tid=0x000001c3e1e8b000 nid=0x50dc runnable

"GC task thread#6 (ParallelGC)" os_prio=0 tid=0x000001c3e1e8e000 nid=0x2e84 runnable

"GC task thread#7 (ParallelGC)" os_prio=0 tid=0x000001c3e1e8f000 nid=0x2c14 runnable

"VM Periodic Task Thread" os_prio=2 tid=0x000001c3f7a46000 nid=0x1d74 waiting on condition

JNI global references: 1087

jmap

主要用于打印指定java进程的共享对象内存映射或堆内存细节。
堆Dump是反映堆使用情况的内存镜像,期中主要包括系统信息、虚拟机属性、完整的线程Dump、所有类和对象的状态等。一般在内存不足、GC异常等情况下,我们回去怀疑内存泄露,这个时候就会去打印堆Dump。

用法

image.png

常用

jmap <pid>:输出结果

image.png 打印的信息分别为:共享对象的起始地址、映射大小、共享对象路径的全称。

jmap -heap :查看堆使用情况,输出结果

Attaching to process ID 6892, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.291-b10

using thread-local object allocation.
Parallel GC with 13 thread(s)

Heap Configuration: //堆内存初始化配置
   MinHeapFreeRatio         = 0 //堆最小空闲比率
   MaxHeapFreeRatio         = 100 //堆最大空闲比率
   MaxHeapSize              = 16823353344 (16044.0MB) //堆最大大小
   NewSize                  = 350748672 (334.5MB) //堆新生代默认大小
   MaxNewSize               = 5607784448 (5348.0MB) //堆新生代最大大小
   OldSize                  = 702021632 (669.5MB) //老年代大小
   NewRatio                 = 2 //新生代和老年代的大小比率
   SurvivorRatio            = 8 //新生代中Eden区与Survivor区的大小比率
   MetaspaceSize            = 21807104 (20.796875MB) //元数据区的初始大小
   CompressedClassSpaceSize = 1073741824 (1024.0MB) //默认1G,这个参数主要是设置Klass Metaspace的大小,不过这个参数设置了也不一定起作用,前提是能开启压缩指针,假如-Xmx超过了32G,压缩指针是开启不来的。如果有Klass Metaspace,那这块内存是和Heap连着的。
   MaxMetaspaceSize         = 17592186044415 MB  //元数据区的最大大小
   G1HeapRegionSize         = 0 (0.0MB)

Heap Usage: //堆内存使用情况
PS Young Generation
Eden Space: //Eden区的内存分布
   capacity = 317194240 (302.5MB)
   used     = 158127136 (150.80178833007812MB)
   free     = 159067104 (151.69821166992188MB)
   49.85183085291839% used
From Space: //其中一个Survivor区的内存分布
   capacity = 11534336 (11.0MB)
   used     = 0 (0.0MB)
   free     = 11534336 (11.0MB)
   0.0% used
To Space: //另一个Survivor区的内存分布
   capacity = 43515904 (41.5MB)
   used     = 0 (0.0MB)
   free     = 43515904 (41.5MB)
   0.0% used
PS Old Generation //老年代内存分布
   capacity = 749207552 (714.5MB)
   used     = 14988656 (14.294296264648438MB)
   free     = 734218896 (700.2057037353516MB)
   2.0006012966617828% used

16736 interned Strings occupying 1486352 bytes.

jmap -histo <pid>:查看堆中对象数量和大小,输出结果

image.png 打印的信息分别是:序列号、对象的数量、这些对象的内存占用大小、这些对象所属的类的全限定名。如果是内部类,类名的开头会加上*,如果加上live子参数的话,如jmaphisto:live<pid>jmap -histo: live <pid>,这个命令会触发一次FULL GC,只统计存活对象.

jmapdump:format=b,file=heapdump<pid>jmap -dump:format=b,file=heapdump <pid>:将内存使用的详细情况输出到文件 然后使用jhat命令查看该文件:jhatport4000filenamejhat -port 4000 filename,在浏览器中访问http://localhost:4000/

总结:该命令适用的场景是程序内存不足或者GC频繁,这时候很可能是内存泄露。通过用以上命令查看堆使用情况、大量对象被持续引用等情况。

jstat

主要是对java应用程序的资源和性能进行实时的命令行监控,包括了对heap size和垃圾回收状况的监控。

用法

image.png

常用

jstatgc<pid>200010jstat -gc <pid> 2000 10

image.png

  • S0C:年轻代第一个Survivor的容量(字节)
  • S1C:年轻代第二个Survivor的容量(字节)
  • S0U:年轻代第一个Survivor已使用的容量(字节)
  • S1U:年轻代第二个Survivor已使用的容量(字节)
  • EC:年轻代中Eden区的空间(字节)
  • EU:年轻代中Eden区已使用的空间(字节)
  • OC:老年代的容量(字节)
  • OU:老年代已使用的容量(字节)
  • MC:Metaspace的容量大小(字节)
  • MU:Metaspace已使用的容量大小(字节)
  • CCSC:压缩类空间的容量大小(字节)
  • CCSU:压缩类空间已使用的容量大小(字节)
  • YGC:从应用程序启动到采样时年轻代中GC的次数
  • YGCT:从应用程序启动到采样时年轻代中GC所使用的时间(单位:S)
  • FGC:从应用程序启动到采样时FULL GC的次数
  • FGCT:从应用程序启动到采样时FULL GC所使用的时间(单位:S)
  • GC:垃圾回收消耗总时间

jstat -gcutil <pid> 2000 10

image.png

  • S0:年轻代第一个Survivor已使用的占当前容量百分比
  • S1:年轻代第二个Survivor已使用的占当前容量百分比
  • E:年轻代中Eden区已使用的占当前容量百分比
  • O:老年代中已使用的占当前容量百分比
  • M:Metaspace已使用的占当前容量百分比(这里有个说法就是说这个Metaspace我们初始设置的很大之后,看到的百分比仍然很高,是因为Metaspace设置的是最大能申请的空间,但是并不会直接申请这么大,这个不太确定)
  • CCS:压缩类空间已使用的占比当前容量百分比

jhat

主要用来解析javadump并启动一个web服务器,然后就可以在浏览器中查看堆的dump文件了。 生成dump文件的方法前面已经介绍过了,这边主要介绍如何解析java堆转储文件,并启动一个web server

jhat heapdump

image.png 访问结果

image.png 这个命令将heapdump文件转换成html格式,并且启动一个http服务,默认端口为7000。 如果端口冲突,可以使用以下命令指定端口:jhatport4000heapdumpjhat -port 4000 heapdump

jinfo

jinfo可以用来查看正在运行的java运用程序的扩展参数,甚至支持在运行时动态地更改部分参数。

用法

jinfo -<option> <pid>,其中option可以为一下信息:

  • flag<name>:打印指定java虚拟机的参数值
  • flag[+|-]<name>:设置或取消指定java虚拟机参数的布尔值
  • flag <name>=<value>:设置指定java虚拟机的参数的值

使用示例:
jinfo -flag MaxTenuringThreshold <pid>:命令显示了新生代对象晋升到老年代对象的最大年龄。在运行程序时并没有指定这个参数,但是通过jinfo,可以查看这个参数的当前的值。

image.png

jinfo -flag PrintGCDetails <pid>:命令显示是否打印gc详细信息:

image.png

jinfo -flag +PrintGCDetails <pid>:命令在应用程序运行时动态打开打印详细gc信息开关:

image.png
注意事项:jinfo虽然可以在java程序运行时动态地修改虚拟机参数,但并不是所有的参数都支持动态修改。

jcmd

在JDK1.7之后,新增了一个命令行工具jcmd。它是一个多功能工具,可以用例导出堆,查看java进程,导出线程信息,执行GC等。jcmd拥有jmap的大部分功能,Oracle官方建议使用jcmd代替jmap

jcmd -l:命令列出当前运行的所有虚拟机,示例:

image.png 针对每个虚拟机,可以使用help命令列出该虚拟机支持的所有命令,示例:

image.png
子命令含义:

  • JFR.stop
  • JFR.start
  • JFR.dump
  • JFR.check
  • VM.native_memory
  • VM.check_commercial_features
  • VM.unlock_commercial_features
  • ManagementAgent.stop
  • ManagementAgent.start_local
  • ManagementAgent.start
  • VM.classloader_stats
  • GC.rotate_log
  • Thread.print 打印线程栈信息
  • GC.class_stats
  • GC.class_histogram 查看系统中类统计信息
  • GC.heap_dump 导出堆信息,与jmap -dump功能一样
  • GC.finalizer_info 触发finalize()
  • GC.heap_info
  • GC.run_finalization
  • GC.run 触发gc()
  • VM.uptime VM启动时间
  • VM.dynlibs
  • VM.flags 获取JVM启动参数
  • VM.system_properties 获取系统Properties
  • VM.command_line 启动时命令行指定的参数
  • VM.version
  • help

示例:

image.png

可视化监控工具(JConsole、JVisualVM)

集上面之大成,并提供了可视化的界面;还可以监控远程java服务;支持监控JVisualVMJVisualVMJConsole更强大:支持对CPU、内存运行进行采样、配置。推荐使用JVisualVM

JConsole

image.png

JVisualVM

image.png

参考

www.cnblogs.com/z-sm/p/6745…

lovestblog.cn/blog/2016/1…