JVM命令行工具

JPS:虚拟机进程状况工具

jps(Java Process Status):显式指定系统内所有的HotSpot虚拟机进程(查看虚拟机进程信息),可用于查询正在运行的虚拟机进程。对于本地虚拟机进程来说,进程的本地虚拟机ID与操作系统的进程ID是一致的,是唯一的。

JPS命令格式

jps [options] [hostid]

options选项参数:

选项 作用
-q 仅仅显式LVMID(local virtual machine id),即本地虚拟机唯一id。不显示主类的名称等
-l 输出应用程序主类的全类名 或 如果进程执行的是jar包,则输出jar完整路径
-m 输出虚拟机进程启动时传递给主类main()的参数
-v 列出虚拟机进程启动时的JVM参数。比如:-Xms20m -Xmx50m 启动程序指定的jvm参数

说明:以上参数可以综合使用。如:jps -lv

补充:如果某Java进程关闭了默认开启的UsePerfData参数(即使用参数-XX:-UsePerfData),那么jps命令(以及jstat)将无法探知该Java进程。

hostid参数:

RMI注册表中注册的主机名。如果想要远程监控主机上的Java程序,需要安装jstatd。

对于具有更严格的安全实践的网络场所而言,可能使用一个自定义的策略文件来显式对特定的可信主机或网络的访问,尽管这种技术容易受到IP地址欺诈个攻击。如果安全问题无法使用一个定制的策略文件来处理,那么最安全的操作是不运行jstatd服务器,而是在本地使用jstat和jps工具。

示例

[root@leizi103 bin]# jps -l
15703 sun.tools.jps.Jps
14027 org.apache.catalina.startup.Bootstrap

jstat:虚拟机统计信息监视工具

jstat(JVM Statistics Monitoring Tool):用于监视虚拟机各种运行状态信息的命令行工具。它可以显示本地或者远程虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据。

在没有GUI图形界面、 只提供了纯文本控制台环境的服务器上, 它将是运行期定位虚拟机性能问题的常用工具。常用于检测垃圾回收问题以及内存泄漏问题。

jstat命令格式

jstat -<option> [-t] [-h<lines>] <vmid> [<interval>[s|ms] [<count>]]
  • option:选项参数。
  • interval:用于指定输出统计数据的周期,单位为毫秒。即:查询隔离时间。
  • count:用于指定查询的总次数。
  • -t:可以在输出信息前加上一个Timestamp列,显式程序的运行时间。单位:秒。
  • -h:可以在周期性数据输出时,输出多少行数据后输出一个表头信息。

查看命令帮助参数:

jstat -h | jstat -help

option选项参数:

  • 类装载相关
选项 作用
-class 显式ClassLoader的相关信息:类的装载、卸载数量、总空间、类装载所消耗的时间等。
  • 垃圾回收相关
选项 作用
-gc 显示与GC相关的堆信息。包括Eden区、两个Survivor区、老年代、元空间等容量、已用空间、GC时间合计等信息。
-gccapacity 显示内容与-gc基本相同,但输出主要关注Java堆各个区域使用到的最大、最小空间。
-gcutil 显示内容与-gc基本相同,但输出主要关注已使用空间占总空间的百分比。
-gccause 与-gcutil功能一样,但是会额外输出导致最后一次或当前正在发生的GC产生的原因。
-gcnew 显示新生代GC状况。
-gcnewcapacity 显示内容与-gcnew基本相同,输出主要关注使用到的最大、最小空间。
-gcold 显示老年代GC状况
  • JIT相关
选项 作用
-compiler 显示JIT编译器编译过的方法、耗时等信息
-printcompilation 输出已经被JIT编译的方法

更多选项见《深入理解Java虚拟机》

详细示例

jstat -gc -t -h5 21396 1000 10

上面指令中 -gc表示选项输出gc相关信息;

-t表示输出程序从开始运行起来到当前采样总时间(单位:秒);

-h5表示每输出5次打印一次表头;

21396表示应用程序进程号;

1000表示间隔1000毫秒打印一次;

10表示打印总次数;

-gc示例

jstat -gc 21396

  • S0C:第一个幸存者区的大小(字节)
  • S1C:第二个幸存者区的大小(字节)
  • S0U:第一个幸存者区已使用的大小(字节)
  • S1U:第二个幸存者区已使用的大小(字节)
  • EC:Eden空间的大小(字节)
  • EU:Eden空间已使用的大小(字节)
  • OC:老年代的大小(字节)
  • OU:老年代已使用的大小(字节)
  • MC:方法区(元空间)的大小
  • MU:方法区(元空间)已使用的大小
  • CCSC:压缩类空间的大小
  • CCSU:压缩类空间已使用的大小
  • YGC:从应用程序启动到采样时young gc次数
  • YGCT:从应用程序启动到采样时young gc消耗的时间(秒)
  • FGC:从应用程序启动到采样时full gc次数
  • FGCT:从应用程序启动到采样时full gc消耗的时间(秒)
  • GCT:从应用程序启动到采样时gc的总时间

-gcutil示例

jstat -gcutil 21396

新生代Eden区(E, 表示Eden)使用了50.37%的空间;

2个Survivor区(S0、S1,表示Survivor0、Survivor1) S0区使用了91.81%的空间;

老年代(O,表示Old) 和元空间(M,表示Meta Space)则分别使用了36.31%和96.51%的空间;

程序运行以来共发生Minor GC(YGC,表示YoungGC)6次,总耗时0.105秒;

发生Full GC(FGC,表示Full GC)0次,总耗时(FGCT,表示Full GCTime)为0.000秒;

所有GC总耗时(GCT,表示GC Time)为0.105秒(YGCT+FGCT=GCT);

-gccause示例

jstat -gccause 21396

与-gcutil功能一样,但是会额外输出导致最后一次或当前正在发生的GC产生的原因。主要看LGCC和GCC可以显示GC产生的原因。Allocation Failure表示新生代空间不足导致产生了GC。

经验

我们可以比较Java进程的启动时间以及总GC时间(GCT),或者两次测量的间隔时间以及总GC时间的增量,来得出GC时间占运行时间的比例。

如果该比例超过20%,则说明目前堆的压力较大;如果该比例超过90%,则说明堆里几乎没有可用空间,随时都可能抛出OOM异常。

jstat -gc -t -h5 21396 1000 100

例如抽样选取两次打印信息,两次程序运行的间隔时间是:2351.1-2331.1=20s,两次gc总时间增量是:0.105-0.105=0(当然我们这里是示例)加入gc增量时间是0.109-0.105=0.004。得出gc时间占运行时间的比例是:0.004/20=0.0002也就是0.02%。

补充

jstat还可以用来判断是否出现内存泄漏。

第一步:在长时间运行的Java程序中,我们可以运行jstat命令连续获取多行性能数据,并取这几行数据中OU列(即已占用的老年代内存)的最小值。

第二步:我们每隔一段较长的时间重复一次上述操作,来获得多组OU最小值(抽样获取)。如果这些值呈上涨趋势,则说明该Java程序的老年代内存已使用量在不断上涨,这意味着无法回收的对象在不断增减,因此很有可能存在内存泄漏。

jinfo:Java配置信息工具

jinfo(Configuration Info for Java)的作用是实时查看和调整虚拟机各项参数。使用jps命令的-v参数可以查看虚拟机启动时显式指定的参数列表,但如果想知道未被显式指定的参数的系统默认值,除了去找资料外,就只能使用jinfo的-flag选项进行查询了(如果只限于JDK 6或以上版本的话,使用javaXX:+PrintFlagsFinal查看参数默认值也是一个很好的选择)。jinfo还可以使用-sysprops选项把虚拟机进程的System.getProperties()的内容打印出来。

jinfo命令格式

jinfo [ option ] pid

说明:java进程ID必须要加上。

option选项参数:

选项 作用
no opton 输出全部的参数和系统属性
-flag name 输出对应名称的参数
-flag [+ | -]name 开启或者关闭对应名称的参数,只有被标记为manageable的参数才可以被动态修改
-flag name=value 设定对应名称的参数
-flags 输出全部的参数
-sysprops 输出系统属性,可以查看有System.getProperties()取得的参数

查看示例

可以查看有System.getProperties()取得的参数

jinfo -sysprops PID

查看曾经赋过值的一些参数

jinfo -flags PID

🌰:

jinfo -flags 21396

查看某个java进程的具体参数的值

jinfo -flag 具体参数 PID

🌰:

[root@leizi103 opt]# jinfo -flag MaxHeapSize 21396
-XX:MaxHeapSize=994050048

修改示例

jinfo不仅可以查看运行时某一个Java虚拟机参数的实际取值,甚至可以在运行时修改部分参数,并使之立即生效。

但是,并非所有参数都支持动态修改。参数只有被标记为manageable的flag可以被实时修改。其实,这个修改能力是极其有限的。

查看被标记为manageable的参数:

java -XX:+PrintFlagsFinal -version | grep manageable

针对boolean类型

jinfo -flag [+ | -]具体参数 PID

🌰:

# 查看参数 PrintGCDetails 是否启用
[root@leizi103 opt]# jinfo -flag PrintGCDetails 21396
-XX:-PrintGCDetails # -:表示未启用
[root@leizi103 opt]# jinfo -flag +PrintGCDetails 21396
[root@leizi103 opt]#
[root@leizi103 opt]# jinfo -flag PrintGCDetails 21396
-XX:+PrintGCDetails# +:表示启用

针对非boolean类型

jinfo -flag 具体参数=具体参数值 PID

🌰:

# 查看参数MaxHeapFreeRatio大小
[root@leizi103 opt]# jinfo -flag MaxHeapFreeRatio 21396
-XX:MaxHeapFreeRatio=100
# 设置参数MaxHeapFreeRatio大小为90
[root@leizi103 opt]# jinfo -flag MaxHeapFreeRatio=90 21396
# 查看参数MaxHeapFreeRatio大小
[root@leizi103 opt]# jinfo -flag MaxHeapFreeRatio 21396
-XX:MaxHeapFreeRatio=90

拓展

查看所有JVM参数启动的初始值

java -XX:+PrintFlagsInitial

查看所有JVM参数的最终值

java -XX:+PrintFlagFinal

查看那些已经被用户或者JVM设置过的详细的XX参数的名称和值

java -XX:+PrintCommandLineFlags

jmap:Java内存映像工具

jmap(Memory Map for Java)命令用于生成堆转储快照(一般称为heapdump或dump二进制文件)。

如果不使用jmap命令,要想获取Java堆转储快照也还有一些比较"暴力"的手段:

-XX:+HeapDumpOnOutOfMemoryError参数,可以让虚拟机在内存溢出异常出现之后自动生成堆转储快照文件。

jmap的作用并不仅仅是为了获取堆转储快照,它还可以查询finalize执行队列、Java堆和方法区的详细信息,如空间使用率、当前用的是哪种收集器等。

jmap命令格式

jmap [ option ] vmid

option选项

常用选项:

选项 作用
-dump 生成Java堆转储快照dump文件,特别的:-dump:live 只保存堆中的存活对象
-heap 输出整个堆空间的详细信息,包括GC的使用、堆配置信息,以及内存的使用信息等
-histo 输出堆空间中对象的统计信息,包括类、实例数量和合计容量。特别的:-histo:live只统计堆中存活的对象

其他选项:

选项 作用
-finalizerinfo 显式在F-Queue中等待Finalizer线程执行finalize方法的对象
-permstat 以ClassLoader为统计口径输出元空间的内存状态信息
-F 当虚拟机进程对 -dump选项没有任何响应时,可使用此选项强制执行生成dump文件
-J <flag> 传递参数给jmap启动的jvm

-dump示例

Heap Dump又叫做对存储文件,指一个Java进程在某个时间点的内存快照。Heap Dump在触发内存快照的时候会保存此刻的信息。

说明:通常在写Heap Dump文件前会触发一次Full GC,所以heap dump文件里保存的都是Full GC后留下的对象信息。

手动方式:

jmap -dump:live,format=b,file=<filename.hprof> <pid>
jmap -dump:live,format=b,file=/home/dump.hprof 5833

自动方式:

当程序发生OOM退出系统时,一些瞬时信息都随着程序的终止而消失,而重现OOM问题往往比较困难或者耗时。此时若能在OOM时,自动导出dump文件就显得非常迫切。

在程序发生OOM时,导出应用程序的当前堆快照:

-XX:+HeapDumpOnOutOfMemoryError

可以指定堆快照的保存位置:

-XX:HeapDumpPath=<filename.hprof>

-heap示例

jmap -heap pid
[root@leizi103 ~]# jmap -heap 2126
Attaching to process ID 2126, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.211-b12
using thread-local object allocation.
Parallel GC with 2 thread(s)
Heap Configuration:
MinHeapFreeRatio = 0
MaxHeapFreeRatio = 100
MaxHeapSize = 994050048 (948.0MB)
NewSize = 20971520 (20.0MB)
MaxNewSize = 331350016 (316.0MB)
OldSize = 41943040 (40.0MB)
NewRatio = 2
SurvivorRatio = 8
MetaspaceSize = 21807104 (20.796875MB)
CompressedClassSpaceSize = 1073741824 (1024.0MB)
MaxMetaspaceSize = 17592186044415 MB
G1HeapRegionSize = 0 (0.0MB)
Heap Usage:
PS Young Generation
Eden Space:
capacity = 201326592 (192.0MB)
used = 86550600 (82.54108428955078MB)
free = 114775992 (109.45891571044922MB)
42.990148067474365% used
From Space:
capacity = 3670016 (3.5MB)
used = 0 (0.0MB)
free = 3670016 (3.5MB)
0.0% used
To Space:
capacity = 4194304 (4.0MB)
used = 0 (0.0MB)
free = 4194304 (4.0MB)
0.0% used
PS Old Generation
capacity = 47710208 (45.5MB)
used = 9202304 (8.7760009765625MB)
free = 38507904 (36.7239990234375MB)
19.287914234203296% used
9684 interned Strings occupying 856264 bytes.

-histo示例

jmap -histo pid
[root@leizi103 ~]# jmap -histo 2126 > /home/histo.txt

文件内容较多展示部分信息如下:

小结

由于jmap将访问堆中的所有对象,为了保证在此过程中不被应用线程干扰,jmap需要借助安全点机制,让所有线程停留在不改变堆中数据的状态。也就是说,由jmap导出的堆快照必定是安全点位置的。这可能导致基于该堆快照的分析结果存在偏差。

举个例子,假设在编译生成的机器码中,某些对象的生命周期在两个安全点之间,那么,:live 选项将无法探知到这些对象。

另外,如果某个线程长时间无法跑到安全点,jmap将一直等下去。与jstat则不同,垃圾回收器会主动将jstat所需要的摘要数据保存至固定位置之中,而jstat只需直接读取即可。

jstack:Java堆栈跟踪工具

jstack(Stack Trace for Java)命令用于生成虚拟机当前时刻的线程快照(一般称为threaddump或者javacore文件)。 线程快照就是当前虚拟机内每一条线程正在执行的方法堆栈的集合。

生成线程快照的目的通常是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间挂起等,都是导致线程长时间停顿的常见原因。线程出现停顿时通过jstack来查看各个线程的调用堆栈,就可以获知没有响应的线程到底在后台做些什么事情,或者等待着什么资源。

在 thread dump中,要留意下面几种状态:

  • 死锁,Deadlock
  • 等待资源,Waiting on condition
  • 等待获取监视器,Waiting on monitor entry
  • 阻塞,Blocked
  • 执行中,Runnable
  • 暂停,Suspended

jstack命令格式

jstack [ option ] pid

option选项

选项 作用
-F 当正常输出的请求不被响应时,强制输出线程堆栈
-l 除堆栈外,显式关于锁的附加信息
-m 如果调用到本地方法的话,可以显式c/c++的堆栈
-h 帮助信息

选项 -l 示例

jstack -l 18483
[root@leizi103 ~]# jstack -l 18483
2022-11-27 15:51:26
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.211-b12 mixed mode):
"Attach Listener" #12 daemon prio=9 os_prio=0 tid=0x00007f384c001000 nid=0x48d6 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"DestroyJavaVM" #11 prio=5 os_prio=0 tid=0x00007f3884009800 nid=0x4834 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"Thread-1" #9 prio=5 os_prio=0 tid=0x00007f38840d1000 nid=0x4842 waiting for monitor entry [0x00007f386fbfa000]
java.lang.Thread.State: BLOCKED (on object monitor)
at ThreadDeadLock$2.run(ThreadDeadLock.java:61)
- waiting to lock <0x00000000ec45aef8> (a java.lang.StringBuilder)
- locked <0x00000000ec45af40> (a java.lang.StringBuilder)
at java.lang.Thread.run(Thread.java:748)
Locked ownable synchronizers:
- None
"Thread-0" #8 prio=5 os_prio=0 tid=0x00007f38840cf000 nid=0x4841 waiting for monitor entry [0x00007f386fcfb000]
java.lang.Thread.State: BLOCKED (on object monitor)
at ThreadDeadLock$1.run(ThreadDeadLock.java:33)
- waiting to lock <0x00000000ec45af40> (a java.lang.StringBuilder)
- locked <0x00000000ec45aef8> (a java.lang.StringBuilder)
Locked ownable synchronizers:
- None
"Service Thread" #7 daemon prio=9 os_prio=0 tid=0x00007f38840ba000 nid=0x483f runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"C1 CompilerThread1" #6 daemon prio=9 os_prio=0 tid=0x00007f38840b7000 nid=0x483e waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"C2 CompilerThread0" #5 daemon prio=9 os_prio=0 tid=0x00007f38840b4000 nid=0x483d waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"Signal Dispatcher" #4 daemon prio=9 os_prio=0 tid=0x00007f38840b2800 nid=0x483c runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"Finalizer" #3 daemon prio=8 os_prio=0 tid=0x00007f388407f800 nid=0x483a in Object.wait() [0x00007f38743b7000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000ec408ed0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144)
- locked <0x00000000ec408ed0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:165)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:216)
Locked ownable synchronizers:
- None
"Reference Handler" #2 daemon prio=10 os_prio=0 tid=0x00007f388407d000 nid=0x4838 in Object.wait() [0x00007f38744b8000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000ec406bf8> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:502)
at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
- locked <0x00000000ec406bf8> (a java.lang.ref.Reference$Lock)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)
Locked ownable synchronizers:
- None
"VM Thread" os_prio=0 tid=0x00007f3884073800 nid=0x4837 runnable
"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007f388401e800 nid=0x4835 runnable
"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00007f3884020800 nid=0x4836 runnable
"VM Periodic Task Thread" os_prio=0 tid=0x00007f38840bc800 nid=0x4840 waiting on condition
JNI global references: 5
Found one Java-level deadlock:
=============================
"Thread-1":
waiting to lock monitor 0x00007f3834002178 (object 0x00000000ec45aef8, a java.lang.StringBuilder),
which is held by "Thread-0"
"Thread-0":
waiting to lock monitor 0x00007f38640062c8 (object 0x00000000ec45af40, a java.lang.StringBuilder),
which is held by "Thread-1"
Java stack information for the threads listed above:
===================================================
"Thread-1":
at ThreadDeadLock$2.run(ThreadDeadLock.java:61)
- waiting to lock <0x00000000ec45aef8> (a java.lang.StringBuilder)
- locked <0x00000000ec45af40> (a java.lang.StringBuilder)
at java.lang.Thread.run(Thread.java:748)
"Thread-0":
at ThreadDeadLock$1.run(ThreadDeadLock.java:33)
- waiting to lock <0x00000000ec45af40> (a java.lang.StringBuilder)
- locked <0x00000000ec45aef8> (a java.lang.StringBuilder)
Found 1 deadlock.

根据上面打印的线程堆栈信息可以看到,Thread-1、Thread-0 线程处于阻塞状态。在下面也给出了死锁的线程和代码位置。

测试代码:

/**
* 演示线程的死锁问题
*/
public class ThreadDeadLock {
public static void main(String[] args) {
StringBuilder s1 = new StringBuilder();
StringBuilder s2 = new StringBuilder();
new Thread(){
@Override
public void run() {
synchronized (s1){
s1.append("a");
s2.append("1");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (s2){
s1.append("b");
s2.append("2");
System.out.println(s1);
System.out.println(s2);
}
}
}
}.start();
new Thread(new Runnable() {
@Override
public void run() {
synchronized (s2){
s1.append("c");
s2.append("3");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (s1){
s1.append("d");
s2.append("4");
System.out.println(s1);
System.out.println(s2);
}
}
}
}).start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(new Runnable() {
@Override
public void run() {
/*从JDK5起,java.lang.Thread类新增了一个getAllStackTraces()方法
用于获取虚拟机中所有线程的StackTraceElement对象。
使用这个方法可以通过简单的几行代码完成jstack的大部分功能,
在实际项目中不妨调用这个方法做个管理员页面,可以随时使用浏览器来查看线程堆栈
*/
Map<Thread, StackTraceElement[]> all = Thread.getAllStackTraces();
Set<Map.Entry<Thread, StackTraceElement[]>> entries = all.entrySet();
for(Map.Entry<Thread, StackTraceElement[]> en : entries){
Thread t = en.getKey();
StackTraceElement[] v = en.getValue();
System.out.println("【Thread name is :" + t.getName() + "】");
for(StackTraceElement s : v){
System.out.println("\t" + s.toString());
}
}
}
}).start();
}
}

jcmd:多功能命令行

在JDK1.7以后,新增了一个命令行工具jcmd。它是一个多功能的工具,可以用来实现前面除了jstat之外所有命令的功能。比如:用它导出堆、内存使用,查看Java进程、导出线程信息,执行GC、JVM运行时间等。

jcmd拥有jmap大部分功能,并且在Oracle的官方网站上也推荐使用jcmd命令代替jmap命令。

列出所有的JVM进程 jcmd -l 示例

相当于 jps -l命令

[root@leizi103 ~]# jcmd -l
21108 ThreadDeadLock
21238 sun.tools.jcmd.JCmd -l
21212 org.apache.catalina.startup.Bootstrap start

jcmd pid help 示例

针对指定的进程,列出支持的所有命令

[root@leizi103 ~]# jcmd 21108 help
21108:
The following commands are available:
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
GC.finalizer_info
GC.heap_info
GC.run_finalization
GC.run
VM.uptime
VM.dynlibs
VM.flags
VM.system_properties
VM.command_line
VM.version
help
For more information about a specific command use 'help <command>'.

显式指定进程的指令命令的数据

具体命令是指上面jcmd pid help显示的具体命令信息,如:Thread.print、VM.flags

jcmd pid 具体命令

相当于 jstack -l 命令的jcmd 21108 Thread.print

[root@leizi103 ~]# jcmd 21108 Thread.print
21108:
2022-11-27 16:17:09
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.211-b12 mixed mode):
"Attach Listener" #12 daemon prio=9 os_prio=0 tid=0x00007f6558001000 nid=0x5404 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"DestroyJavaVM" #11 prio=5 os_prio=0 tid=0x00007f658c009800 nid=0x5275 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Thread-1" #9 prio=5 os_prio=0 tid=0x00007f658c0e1000 nid=0x5281 waiting for monitor entry [0x00007f65773f2000]
java.lang.Thread.State: BLOCKED (on object monitor)
at ThreadDeadLock$2.run(ThreadDeadLock.java:58)
- waiting to lock <0x00000000ec45aef8> (a java.lang.StringBuilder)
- locked <0x00000000ec45af40> (a java.lang.StringBuilder)
at java.lang.Thread.run(Thread.java:748)
"Thread-0" #8 prio=5 os_prio=0 tid=0x00007f658c0df000 nid=0x5280 waiting for monitor entry [0x00007f65774f3000]
java.lang.Thread.State: BLOCKED (on object monitor)
at ThreadDeadLock$1.run(ThreadDeadLock.java:30)
- waiting to lock <0x00000000ec45af40> (a java.lang.StringBuilder)
- locked <0x00000000ec45aef8> (a java.lang.StringBuilder)

相当于jstat -gc -t 21108jcmd 21108 VM.uptime查看应用程序运行时间

[root@leizi103 ~]# jcmd 21108 VM.flags
21108:
-XX:CICompilerCount=2 -XX:InitialHeapSize=62914560 -XX:MaxHeapSize=994050048 -XX:MaxNewSize=331350016 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=20971520 -XX:OldSize=41943040 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseParallelGC

其他命令行工具说明

截取《深入理解Java虚拟机 第3版》第二部分第4章4.2.7节,如下:

posted @   Lz_蚂蚱  阅读(131)  评论(0编辑  收藏  举报
历史上的今天:
2021-11-27 Logback日志
2021-11-27 Maven深入
2021-11-27 Maven入门
2021-11-27 Maven简介与Maven相关概念
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起