JDK 中与常用命令行工具
jps
查看当前服务器正在执行的 Java 进程
$> jps
7584 Application
16433 AdminApplication
14209 Jps
5813 Bootstrap
5575 TestApplication
7160 Application
6010 Bootstrap
6715 Bootstrap
3981 QuorumPeerMain
6527 jar
这里的进程id和操作系统的进程id是一致的。第二列是显示的当前正在执行的 Java 程序的名称。
$> jps -help
usage: jps [-help]
jps [-q] [-mlvV] [<hostid>]
Definitions:
<hostid>: <hostname>[:<port>]
- l 显示类的完整信息
- v 显示启动时的 Java 配置选项
jstat
查看当前Java进程的相关信息(GC信息、类加载信息、JIT编译信息等)
$> jstat -help
Usage: jstat -help|-options
jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]
Definitions:
<option> 通过 -options 可以查看有哪些option
<vmid> 进程id,如果是远程格式如下:<远程的进程id>[@<hostname>[:<port>]]
<lines> 打印多少行之后再次显示一下表头.
<interval> 打印间隔时间格式为:<n>["ms"|"s"]
<count> 重复打印的次数,如果设置了 interval 而不设置时间,则一直打印.
-J<flag> 将 <flag> 的值传递给运行时系统.
-t 程序执行时长
-h<lines> 打印多少行之后再次显示一下表头
$> jstat -options
-class 显示 ClassLoader 的相关信息
-compiler 显示 JIT 编译的信息
-gc 显示 GC 相关信息
-gccapacity 堆内存 -gc
-gccause 显示发生 GC 的原因
-gcmetacapacity 元空间 GC 信息
-gcnew 新生代信息
-gcnewcapacity 类似于 -gcnew
-gcold 老年代信息
-gcoldcapacity 类似于 -gcnew
-gcutil 垃圾回收统计概述
-printcompilation 显示 JIT 编译的信息
jstat -gc GC 日志
$> jstat -gc 进程id 1s 5
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
512.0 512.0 128.0 0.0 36864.0 29170.4 152064.0 72123.0 105088.0 99428.9 12416.0 11352.7 920 22.131 4 1.018 23.149
S0C:幸存者0区的总内存大小
S0U:幸存者0区已经使用的内存大小
EC、EU: Eden 区的总内存大小和已经使用的内存大小
OC、OU:老年代的内存信息
MC、MU:元空间的内存信息
C 即 Capacity 总容量,U 即 Used 已使用的容量
YGC:YoungGC 的次数
YGCT:YoungGC 的时间
FGC:FGC 老年代GC次数
FGCT:FGC 老年代GC的时间
GCT:总 GC 的时间
| 字段 | 说明 |
|---|---|
| S0C | 年轻代第一个Survivor区的大小(单位:KB) |
| S1C | 年轻代第二个Survivor区的大小(单位:KB) |
| S0U | 年轻代第一个Survivor区的使用大小(单位:KB) |
| S1U | 年轻代第二个Survivor区的使用大小(单位:KB) |
| EC | 年轻代中Eden区的大小(单位:KB) |
| EU | 年轻代中Eden区的使用大小(单位:KB) |
| OC | 老年代大小(单位:KB) |
| OU | 老年代使用大小(单位:KB) |
| MC | 方法区大小(单位:KB) |
| MU | 方法区使用大小(单位:KB) |
| CCSC | 压缩类空间大小(单位:KB) |
| CCSU | 压缩类空间使用大小(单位:KB) |
| YGC | 年轻代垃圾回收次数 |
| YGCT | 年轻代垃圾回收消耗时间 |
| FGC | 老年代垃圾回收次数 |
| FGCT | 老年代垃圾回收消耗时间 |
| GCT | 垃圾回收消耗总时间 |
jstat -class class loader 统计
$> jstat -class pid
Loaded Bytes Unloaded Bytes Time
61273 121122.0 937 1041.5 29.84
| 字段 | 说明 |
|---|---|
| Loaded | 加载class的数量。 |
| Bytes | class字节大小。 |
| Unloaded | 未加载class的数量。 |
| Bytes | 未加载class的字节大小。 |
| Time | 加载时间。 |
jstat -gccapacity 堆内存统计
$> jstat -gccapacity pid
NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC
0.0 2097152.0 660480.0 0.0 14336.0 646144.0 0.0 2097152.0 388096.0 388096.0 0.0 1376256.0 363392.0 0.0 1048576.0 45632.0 73 0
| 字段 | 说明 |
|---|---|
| NGCMN | 新生代最小容量 |
| NGCMX | 新生代最大容量 |
| NGC | 当前新生代容量 |
| S0C | 第一个Survivor区大小 |
| S1C | 第二个Survivor区的大小 |
| EC | Eden区的大小 |
| OGCMN | 老年代最小容量 |
| OGCMX | 老年代最大容量 |
| OGC | 当前老年代大小 |
| OC | 当前老年代大小 |
| MCMN | 最小元数据容量 |
| MCMX | 最大元数据容量 |
| MC | 当前元数据空间大小 |
| CCSMN | 最小压缩类空间大小 |
| CCSMX | 最大压缩类空间大小 |
| CCSC | 当前压缩类空间大小 |
| YGC | 年轻代gc次数 |
| FGC | 老年代GC次数 |
jstat -compiler JIT编译器行为统计
$> jstat -compiler pid
Compiled Failed Invalid Time FailedType FailedMethod
64606 3 0 77.49 1 jdk/internal/net/http/hpack/QuickHuffman addLeaf
| 字段 | 说明 |
|---|---|
| Compiled | 编译数量。 |
| Failed | 编译失败数量。 |
| Invalid | 无效数量。 |
| Time | 编译耗时。 |
| FailedType | 失败类型。 |
| FailedMethod | 失败方法的全限定名。 |
jstat -gcutil 总体垃圾回收统计
$> jstat -gcutil pid
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
- 86.27 14.22 78.13 98.78 94.99 74 0.809 0 0.000 0.809
| 字段 | 说明 |
|---|---|
| S0 | 第一个Servivor区当前使用比例 |
| S1 | 第二个Servivor区当前使用比例 |
| E | Eden区使用比例 |
| O | 老年代使用比例 |
| M | 元数据区使用比例 |
| CCS | 压缩使用比例 |
| YGC | 年轻代垃圾回收次数 |
| FGC | 老年代垃圾回收次数 |
| FGCT | 老年代垃圾回收消耗时间 |
| GCT | 垃圾回收消耗总时间 |
jstat -gccause 总体垃圾回收统计
$> jstat -gccause pid
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT LGCC GCC
- 86.27 28.12 78.13 98.78 94.99 74 0.809 0 0.000 0.809 G1 Evacuation Pause No GC
| 字段 | 说明 |
|---|---|
| S0 | 第一个Servivor区当前使用比例 |
| S1 | 第二个Servivor区当前使用比例 |
| E | Eden区使用比例 |
| O | 老年代使用比例 |
| M | 元数据区使用比例 |
| CCS | 压缩使用比例 |
| YGC | 年轻代垃圾回收次数 |
| FGC | 老年代垃圾回收次数 |
| FGCT | 老年代垃圾回收消耗时间 |
| GCT | 垃圾回收消耗总时间 |
| LGCC | 最近垃圾回收的原因 |
| GCC | 当前垃圾回收的原因 |
jstat -gcnew 新生代垃圾回收统计
$> jstat -gcnew pid
S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT
0.0 5120.0 0.0 4417.2 15 15 39424.0 655360.0 228352.0 74 0.809
| 字段 | 说明 |
|---|---|
| S0C | 第一个Survivor区大小 |
| S1C | 第二个Survivor区的大小 |
| S0U | 第一个Survivor区的使用大小 |
| S1U | 第二个Survivor区的使用大小 |
| TT | 对象在新生代存活的次数 |
| MTT | 对象在新生代存活的最大次数 |
| DSS | 期望的Survivor区大小 |
| EC | Eden区的大小 |
| EU | Eden区的使用大小 |
| YGC | 年轻代垃圾回收次数 |
| YGCT | 年轻代垃圾回收消耗时间 |
jstat -gcnewcapacity 新生代内存统计
$> jstat -gcnewcapacity pid
NGCMN NGCMX NGC S0CMX S0C S1CMX S1C ECMX EC YGC FGC
0.0 2097152.0 660480.0 0.0 0.0 2097152.0 5120.0 2097152.0 655360.0 74 0
| 字段 | 说明 |
|---|---|
| NGCMN | 新生代最小容量 |
| NGCMX | 新生代最大容量 |
| NGC | 当前新生代容量 |
| S0CMX | 第一个Survivor区最大大小 |
| S0C | 第一个Survivor区当前大小 |
| S1CMX | 第二个Survivor区最大大小 |
| S1C | 第二个Survivor区当前大小 |
| ECMX | Eden区最大大小 |
| EC | Eden区当前大小 |
| YGC | 年轻代垃圾回收次数 |
| FGC | 老年代回收次数 |
jstat -gcold 老年代垃圾回收统计
$> jstat -gcold pid
MC MU CCSC CCSU OC OU YGC FGC FGCT GCT
363392.0 358958.6 45632.0 43344.2 388096.0 303216.5 74 0 0.000 0.809
| 字段 | 说明 |
|---|---|
| MC | 方法区大小 |
| MU | 方法区使用大小 |
| CCSC | 压缩类空间大小 |
| CCSU | 压缩类空间使用大小 |
| OC | 老年代大小 |
| OU | 老年代使用大小 |
| YGC | 年轻代垃圾回收次数 |
| FGC | 老年代垃圾回收次数 |
| FGCT | 老年代垃圾回收消耗时间 |
| GCT | 垃圾回收消耗总时间 |
jstat -gcoldcapacity 老年代内存统计
$> jstat -gcoldcapacity pid
OGCMN OGCMX OGC OC YGC FGC FGCT GCT
0.0 2097152.0 388096.0 388096.0 74 0 0.000 0.809
| 字段 | 说明 |
|---|---|
| OGCMN | 老年代最小容量 |
| OGCMX | 老年代最大容量 |
| OGC | 当前老年代大小 |
| OC | 老年代大小 |
| YGC | 年轻代垃圾回收次数 |
| FGC | 老年代垃圾回收次数 |
| FGCT | 老年代垃圾回收消耗时间 |
| GCT | 垃圾回收消耗总时间 |
jstat -gcmetacapacity 元空间内存统计
$> jstat -gcmetacapacity pid
MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC FGCT GCT
0.0 1376256.0 363392.0 0.0 1048576.0 45632.0 74 0 0.000 0.809
| 字段 | 说明 |
|---|---|
| MCMN | 最小元数据容量 |
| MCMX | 最大元数据容量 |
| MC | 当前元数据空间大小 |
| CCSMN | 最小压缩类空间大小 |
| CCSMX | 最大压缩类空间大小 |
| CCSC | 当前压缩类空间大小 |
| YGC | 年轻代垃圾回收次数 |
| FGC | 老年代垃圾回收次数 |
| FGCT | 老年代垃圾回收消耗时间 |
| GCT | 垃圾回收消耗总时间 |
jstat -printcompilation 编译内容统计
$> jstat -printcompilation pid
Compiled Size Type Method
64715 14 1 com/fasterxml/jackson/databind/introspect/AnnotatedConstructor getParameterCount
| 字段 | 说明 |
|---|---|
| Compiled | 被执行的编译任务的数量 |
| Size | 方法字节码的字节数 |
| Type | 编译类型 |
| Method | 编译方法的类名和方法名。类名使用"/" 代替 “.” 作为空间分隔符. 方法名是给出类的方法名。可使用JVM 的 - XX:+PrintComplation 选项配置格式 |
jinfo
查看或修改JVM配置参数信息
$> jinfo -help
Usage:
jinfo [option] <pid>
(to connect to running process)
jinfo [option] <executable <core>
(to connect to a core file)
jinfo [option] [server_id@]<remote server IP or hostname>
(to connect to remote debug server)
where <option> is one of:
-flag <name> to print the value of the named VM flag
-flag [+|-]<name> to enable or disable the named VM flag
-flag <name>=<value> to set the named VM flag to the given value
-flags to print VM flags
-sysprops to print Java system properties
<no option> to print both of the above
-h | -help to print this help message
示例
$> jinfo -flags 进程id
Attaching to process ID 进程id, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.181-b13
Non-default VM flags: -XX:CICompilerCount=3 -XX:InitialHeapSize=130023424 -XX:MaxHeapSize=2051014656 -XX:MaxNewSize=683671552 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=42991616 -XX:OldSize=87031808 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseParallelGC
Command line:
jinfo 命令可以动态修改Java 进程配置,配置之后立即生效。但并不是所有的选项参数都能修改,需要是标记为 manageable 的才能修改。
$> java -XX:+PrintFlagsFinal -version | grep manageable
intx CMSAbortablePrecleanWaitMillis = 100 {manageable}
intx CMSTriggerInterval = -1 {manageable}
intx CMSWaitDuration = 2000 {manageable}
bool HeapDumpAfterFullGC = false {manageable}
bool HeapDumpBeforeFullGC = false {manageable}
bool HeapDumpOnOutOfMemoryError = false {manageable}
ccstr HeapDumpPath = {manageable}
uintx MaxHeapFreeRatio = 100 {manageable}
uintx MinHeapFreeRatio = 0 {manageable}
bool PrintClassHistogram = false {manageable}
bool PrintClassHistogramAfterFullGC = false {manageable}
bool PrintClassHistogramBeforeFullGC = false {manageable}
bool PrintConcurrentLocks = false {manageable}
bool PrintGC = false {manageable}
bool PrintGCDateStamps = false {manageable}
bool PrintGCDetails = false {manageable}
bool PrintGCID = false {manageable}
bool PrintGCTimeStamps = false {manageable}
注意:动态修改只能针对当前的进程,当我们的应用重启之后进程其实就变了,所以这里的动态修改也就是在线排查或在线调优的时候用一用。
jmap
导出 JVM 内存映射,它可以获取 dump 文件,还可以获取进程的内存相关信息,包括各区域的使用情况等
$> jmap -help
Usage:
jmap [option] <pid>
(to connect to running process)
jmap [option] <executable <core>
(to connect to a core file)
jmap [option] [server_id@]<remote server IP or hostname>
(to connect to remote debug server)
where <option> is one of:
<none> to print same info as Solaris pmap
-heap to print java heap summary
-histo[:live] to print histogram of java object heap; if the "live"
suboption is specified, only count live objects
-clstats to print class loader statistics
-finalizerinfo to print information on objects awaiting finalization
-dump:<dump-options> to dump java heap in hprof binary format
dump-options:
live dump only live objects; if not specified,
all objects in the heap are dumped.
format=b binary format
file=<file> dump heap to <file>
Example: jmap -dump:live,format=b,file=heap.bin <pid>
-F force. Use with -dump:<dump-options> <pid> or -histo
to force a heap dump or histogram when <pid> does not
respond. The "live" suboption is not supported
in this mode.
-h | -help to print this help message
-J<flag> to pass <flag> directly to the runtime system
导出 dump 文件
## jmap -dump:format=b,file=<fileName.hprof> <pid>
## 只导出存活对象 jmap -dump:live,format=b,file=<fileName.hprof> <pid>
$> jmap -dump:format=b,file=test.hprof 进程id
Dumping heap to /home/test/test.hprof ...
Heap dump file created
导出后我们可能需要使用相关的工具才能分析 dump 文件,这个我们后面再说。
以上为使用 jmap 命令进行导出。我们在前面文章 《JVM GC 垃圾收集器》中提到 -XX:HeapDumpPath 和 -XX:+HeapDumpOnOutOfMemoryError 参数组合也会导出 dump 文件,区别在于,自动导出时是因为触发了 FullGC。
- -XX:HeapDumpPath=path
将 OutOfMemoryError 转储到 .hprof 文件,此设置虚配合 -XX:+HeapDumpOnOutOfMemoryError 一起使用
示例:-XX:HeapDumpPath=./java_pid%p.hprof , %p 表示进程id
- -XX:+HeapDumpOnOutOfMemoryError
当出现 java.lang.OutOfMemoryError 异常,则将根据 -XX:HeapDumpPath=path 配置输出 .hprof 文件
查看堆内存信息
## jmap -heap <pid> 显示堆内存当前的使用情况
## jmap -histo[:live] <pid> 统计所有[存活]的对象并统计其占用内存信息以及对象个数等
$> jmap -heap 进程id
Attaching to process ID 进程id, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.181-b13
using thread-local object allocation.
Parallel GC with 4 thread(s)
# 堆空间的配置信息
Heap Configuration:
MinHeapFreeRatio = 0
MaxHeapFreeRatio = 100
MaxHeapSize = 2051014656 (1956.0MB)
NewSize = 42991616 (41.0MB)
MaxNewSize = 683671552 (652.0MB)
OldSize = 87031808 (83.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: # Eden 区信息
capacity = 38797312 (37.0MB)
used = 35691760 (34.03831481933594MB)
free = 3105552 (2.9616851806640625MB)
91.9954454576647% used
From Space: # from 区信息
capacity = 524288 (0.5MB)
used = 131072 (0.125MB)
free = 393216 (0.375MB)
25.0% used
To Space: # to 区信息
capacity = 524288 (0.5MB)
used = 0 (0.0MB)
free = 524288 (0.5MB)
0.0% used
PS Old Generation # 老年代信息
capacity = 195559424 (186.5MB)
used = 54819320 (52.27977752685547MB)
free = 140740104 (134.22022247314453MB)
28.03205229322009% used
34583 interned Strings occupying 4040496 bytes.
从以上信息我们可以知道,当前进程中,大部分对象都在老年代,说明我们的很多对象生命周期过长了。
jstack
打印 Java 进程、核心文件或远程调试服务器的 Java 线程堆栈跟踪。
$> jstack -help
Usage:
jstack [-l] <pid>
(to connect to running process) # 连接正在执行的进程
jstack -F [-m] [-l] <pid>
(to connect to a hung process) # 连接到挂起的进程
jstack [-m] [-l] <executable> <core>
(to connect to a core file) #
jstack [-m] [-l] [server_id@]<remote server IP or hostname>
(to connect to a remote debug server)
Options:
-F to force a thread dump. Use when jstack <pid> does not respond (process is hung) # 强制打印
-m to print both java and native frames (mixed mode) # 打印具有 Java 和本机 C/C++ 帧的混合模式堆栈跟踪
-l long listing. Prints additional information about locks # 打印有关锁的附加信息
-h or -help to print this help message
示例
$> jstack 进程id
2023-10-10 21:28:17
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.181-b13 mixed mode):
"Attach Listener" #440036 daemon prio=9 os_prio=0 tid=0x00007fd96001f800 nid=0x324c waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE # 当前线程的状态 RUNNABLE 、WAITING都算正常 TIME_WAITTING 程序 sleep 中
"Java2D Disposer" #77543 daemon prio=10 os_prio=0 tid=0x00007fd91005b800 nid=0x45e0 in Object.wait() [0x00007fd900dd4000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144)
- locked <0x0000000088ce20b0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:165)
at sun.java2d.Disposer.run(Disposer.java:148)
at java.lang.Thread.run(Thread.java:748)
"logback-8" #50912 daemon prio=5 os_prio=0 tid=0x00007fd9740d3800 nid=0x296c waiting on condition [0x00007fd8ffecf000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000885336a0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1081)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
"logback-7" #44036 daemon prio=5 os_prio=0 tid=0x00007fd9740d3000 nid=0x75e8 waiting on condition [0x00007fd8fffd0000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000885336a0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1081)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
"logback-6" #37255 daemon prio=5 os_prio=0 tid=0x00007fd97407a000 nid=0x32ac waiting on condition [0x00007fd93e4b7000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000885336a0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1081)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
显示出的状态包括如下几个:
- DeadLock:死锁
- Waiting on condition:等待资源
- Waiting on monitor entry:等待获取监视器
- Blocked:阻塞
- Runnable:执行中
- Suspend:暂停
- 其他
这其中死锁、等待资源、等待获取监视器、阻塞等情况需要进行重点关注。
关于命令的详细参数选项以及说明可以参考官网 https://docs.oracle.com/javase/8/docs/technotes/tools/unix/index.html
JVM 可视化分析工具
- jconsole JDK bin 目录下
- jvisualvm JDK bin 目录下,也可以直接下载相关 Visualvm 软件。idea 中可以使用 VisualVM Launcher 插件来快速启动。Visualvm 本身也有许多有用的插件。
- JMC JDK bin 目录下
- Eclipse MAT(Memory Analyzer Tool) Eclipse 推出的内存分析工具,也可以在 Eclipse 中通过插件引入。其特点是开源免费,老牌 IDE Eclipse 出品,功能也挺多的,可直接下载 MAT 软件启动,也可以在 Eclipse 中通过插件引入。
- JProfiler:商业付费,idea 有快速启动其的同名插件。界面清晰,功能强大,目前最新的 14.0 版本是支持中文显示界面的。14.0 版本官方教程文档 https://www.ej-technologies.com/resources/jprofiler/v/14.0/help_zh_CN/doc/main/introduction.html
- Arthas:阿里开源,它是可以在生产环境进行运行分析的,官方说明是,它可以不停止应用对应用进行分析,且不会像远程调试一样会阻塞应用执行。官网地址为:https://arthas.aliyun.com/
本文介绍了JDK中的四个常用命令行工具:jps用于查看Java进程,jstat监控Java进程信息,jinfo修改JVM配置,jmap导出堆内存映射。此外,还提及了JVM可视化分析工具如jconsole、jvisualvm、JMC和JProfiler,以及Arthas的特性。

被折叠的 条评论
为什么被折叠?



