专栏原创出处:github-源笔记文件 (opens new window) ,github-源码 (opens new window),欢迎 Star,转载请附上原文出处链接和本声明。
Java JVM-虚拟机专栏系列笔记,系统性学习可访问个人复盘笔记-技术博客 Java JVM-虚拟机 (opens new window)
# 前言
本内容基于 OracleJDK 13,对应官方文档:Java® Development Kit Version 13 Tool Specifications (opens new window)
如果使用 OpenJDK 时,可能每个命令支持的用法会有差异,可使用 命令 -h
查看,例如:jmap
在 OpenJDK 下支持的选项更多。
给一个系统定位问题的时候,知识、经验是关键基础,数据是依据,工具是运用知识处理数据的手段。这里说的数据包括但不限于虚拟机信息,异常堆栈、虚拟机运行日志、GC日志、线程快照(threaddump/javacore 文件)、堆转储快照(heapdump/hprof 文件)等。 恰当地使用虚拟机故障处理、分析的工具可以提升我们分析数据、定位并解决问题的效率。
因内容较多多,请根据目录查看对应命令概念及用法介绍。关于如何应用这些命令参考本专栏相关文章。
# jps:虚拟机进程状况工具
jps 命令用来查看所有 Java 进程,每一行就是一个 Java 进程信息。
jps 仅查找当前用户的 Java 进程,而不是当前系统中的所有进程,要显示其他用户的还只能用 ps 命令。
用法:
jps [ -q] [ -mlvV] [ hostid ]
jps [ -help]
Options:
-q 禁止类名称,JAR 文件名和传递给该 main 方法的参数的输出,从而仅生成本地 JVM 标识符的列表。
-mlvV 您可以指定这些选项的任意组合。
-m 显示传递给 main 方法的参数。输出可能是 null 针对嵌入式 JVM 的。
-l 显示应用程序 main 类的完整软件包名称或应用程序 JAR 文件的完整路径名称。
-v 显示传递给 JVM 的参数。
-V 禁止输出类名,JAR 文件名和传递给该 main 方法的参数的输出,从而仅生成本地 JVM 标识符的列表。
示例:
$jps -ml
769 org.jetbrains.idea.maven.server.RemoteMavenServer36
2376 sun.tools.jps.Jps -ml
731
# jstat:虚拟机统计信息监视工具
用法:
jstat generalOptions
jstat outputOptions [-t] [-h lines] vmid [interval [count]]
Options:
outputOptions:参数选项,可以从下面参数中选择(具体信息参考 #outputOptions 小节)
- -class : 显示 ClassLoad 的相关信息;
- -compiler : 显示 JIT 编译的相关信息;
- -gc : 显示和 gc 相关的堆信息;
- -gccapacity : 显示各个代的容量以及使用情况;
- -gcmetacapacity : 显示 metaspace 的大小
- -gcnew : 显示新生代信息;
- -gcnewcapacity : 显示新生代大小和使用情况;
- -gcold : 显示老年代和永久代的信息;
- -gcoldcapacity : 显示老年代的大小;
- -gcutil : 显示垃圾收集信息;
- -gccause : 显示垃圾回收的相关信息(通-gcutil),同时显示最后一次或当前正在发生的垃圾回收的诱因;
- -printcompilation : 输出 JIT 编译的方法信息
-t : 可以在打印的列加上 Timestamp 列,用于显示系统运行的时间
-h : 可以在周期性数据数据的时候,可以在指定输出多少行以后输出一次表头
vmid : Virtual Machine ID( 进程的 pid)
interval : 执行每次的间隔时间,单位为毫秒
count : 用于指定输出多少次记录,缺省则会一直打印
示例:
$jstat -gc -t -h 5 769 500 10
Timestamp S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
4138.2 0.0 0.0 0.0 0.0 12288.0 0.0 18432.0 7740.2 24064.0 23254.2 2816.0 2593.3 4 0.036 1 0.059 0.095
4138.7 0.0 0.0 0.0 0.0 12288.0 0.0 18432.0 7740.2 24064.0 23254.2 2816.0 2593.3 4 0.036 1 0.059 0.095
4139.3 0.0 0.0 0.0 0.0 12288.0 0.0 18432.0 7740.2 24064.0 23254.2 2816.0 2593.3 4 0.036 1 0.059 0.095
4139.7 0.0 0.0 0.0 0.0 12288.0 0.0 18432.0 7740.2 24064.0 23254.2 2816.0 2593.3 4 0.036 1 0.059 0.095
4140.3 0.0 0.0 0.0 0.0 12288.0 0.0 18432.0 7740.2 24064.0 23254.2 2816.0 2593.3 4 0.036 1 0.059 0.095
Timestamp S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
4140.8 0.0 0.0 0.0 0.0 12288.0 0.0 18432.0 7740.2 24064.0 23254.2 2816.0 2593.3 4 0.036 1 0.059 0.095
4141.3 0.0 0.0 0.0 0.0 12288.0 0.0 18432.0 7740.2 24064.0 23254.2 2816.0 2593.3 4 0.036 1 0.059 0.095
4141.8 0.0 0.0 0.0 0.0 12288.0 0.0 18432.0 7740.2 24064.0 23254.2 2816.0 2593.3 4 0.036 1 0.059 0.095
4142.3 0.0 0.0 0.0 0.0 12288.0 0.0 18432.0 7740.2 24064.0 23254.2 2816.0 2593.3 4 0.036 1 0.059 0.095
# outputOptions 选择
# -class 选项
类加载器统计信息
- Loaded:已加载的类数
- Bytes:装载类所占用的 KB 数
- Unloaded:卸载的类数
- Bytes:卸载类的 KB 数
- Time:装载和卸载类所花费的时间
# -compiler 选项
Java HotSpot VM 即时编译器统计信息
- Compiled:执行的编译任务数
- Failed:编译任务数失败
- Invalid:无效的编译任务数
- Time:执行编译任务所花费的时间
- FailedType:上次失败的编译的编译类型
- FailedMethod:上次失败的编译的类名和方法
# -gc 选项
垃圾收集的堆统计信息
- S0C:Survivor 0 容量(KB)
- S1C:Survivor 1 容量(KB)
- S0U:Survivor 0 已使用空间(KB)
- S1U:Survivor 1 已使用空间(KB)
- EC:Eden 空间容量(KB)
- EU:Eden 已使用空间(KB)
- OC:老年代容量(KB)
- OU:已使用空间(KB)
- MC:元空间容量(KB)
- MU:元空间已使用空间(KB)
- CCSC:压缩类空间大小(KB)
- CCSU:压缩类空间使用大小(KB)
- YGC:年轻代垃圾收集(GC)事件的数量
- YGCT:年轻代垃圾回收时间
- FGC:Full GC 事件的数量
- FGCT:Full GC 收集时间
- GCT:总垃圾收集时间
# -gccapacity 选项
内存池的生成和空间容量
- NGCMN:年轻代最小容量(KB)
- NGCMX:年轻代最大容量(KB)
- NGC:当前年轻代容量(KB)
- S0C:当前 Survivor 0 容量(KB)
- S1C:当前 Survivor 1 容量(KB)
- EC:当前 Eden 空间容量(KB)
- OGCMN:老年代最小容量(KB)
- OGCMX:老年代最大容量(KB)
- OGC:当前老年代容量(KB)
- OC:老年代容量(KB)
- MCMN:元空间最小容量(KB)
- MCMX:元空间最大容量(KB)
- MC:当前元空间的容量(KB)
- CCSMN:压缩的类空间最小容量(KB)
- CCSMX:压缩的类空间最大容量(KB)
- CCSC:当前压缩类空间大小(KB)
- YGC:年轻代 GC 事件的数量
- FGC:Full GC 事件的数量
# -gccause 选项
显示垃圾回收的相关信息
LGCC:上次垃圾回收的原因
GCC:当前垃圾收集的原因
# -gcnew 选项
年轻代当前统计数据
- S0C:Survivor 0 容量(KB)
- S1C:Survivor 1 容量(KB)
- S0U:Survivor 0 已使用容量(KB)
- S1U:Survivor 1 已使用容量(KB)
- TT:持有次数限制
- MTT:最大持有次数限制
- DSS:期望的 Survivor 大小(KB)
- EC:Eden 空间容量(KB)
- EU:Eden 已使用容量(KB)
- YGC:年轻代 GC 事件的数量
- YGCT:年轻代垃圾回收时间
# -gcnewcapacity 选项
年轻代当前空间大小统计信息
- NGCMN:年轻代最小容量(KB)
- NGCMX:年轻代最大容量(KB)
- NGC:当前年轻代容量(KB)
- S0CMX:Survivor 0 最大容量(KB)
- S0C:当前 Survivor 0 容量(KB)
- S1CMX:Survivor 1 最大容量(KB)
- S1C:当前 Survivor 1 容量(KB)
- ECMX:Eden 最大空间容量(KB)
- EC:当前 Eden 空间容量(KB)
- YGC:年轻代 GC 事件的数量
- FGC:Full GC 事件的数量
# -gcold 选项
老年代对象信息统计
- MC:元空间容量(KB)
- MU:元空间已使用容量(KB)
- CCSC:压缩的类提交大小(KB)
- CCSU:使用的压缩类空间(KB)
- OC:老年代容量(KB)
- OU:老年代已使用容量(KB)
- YGC:年轻代 GC 事件的数量
- FGC:Full GC 事件的数量
- FGCT:Full GC 收集时间
- GCT:总垃圾收集时间
# -gcoldcapacity 选项
老年代统计数据
- OGCMN:老年代最小容量(KB)
- OGCMX:老年代最大容量(KB)
- OGC:当前老年代容量(KB)
- OC:老年代容量(KB)
- YGC:年轻代 GC 事件的数量
- FGC:Full GC 事件的数量
- FGCT:Full GC 收集时间
- GCT:总垃圾收集时间
# -gcmetacapacity 选项
元空间大小统计信息
- MCMN:元空间最小容量(KB)
- MCMX:元空间最大容量(KB)
- MC:当前元空间的容量(KB)
- CCSMN:压缩的类空间最小容量(KB)
- CCSMX:压缩的类空间最大容量(KB)
- YGC:年轻代 GC 事件的数量
- FGC:Full GC 事件的数量
- FGCT:Full GC 收集时间
- GCT:总垃圾收集时间
# -gcutil 选项
垃圾收集统计信息摘要
- S0:Survivor 0 利用率占该空间当前容量的百分比
- S1:Survivor 1 利用率占空间当前容量的百分比
- E:Eden 空间利用率占空间当前容量的百分比
- O:老年代利用率占空间当前容量的百分比
- M:元空间利用率占空间当前容量的百分比
- CCS:压缩的类空间利用率(以百分比表示)
- YGC:年轻代 GC 事件的数量
- YGCT:年轻代垃圾回收时间
- FGC:Full GC 事件的数量
- FGCT:Full GC 收集时间
- GCT:总垃圾收集时间
# -printcompilation 选项
Java HotSpot VM 编译器方法统计信息
- Compiled:编译方法执行的编译任务数
- Size:编译方法生成字节码的字节数
- Type:编译方法的编译类型
- Method:标识最近编译的方法的类名和方法名。类名使用斜杠(/)代替点(。)作为名称空间分隔符。方法名称是指定类中的方法。这两个字段的格式与 HotSpot -XX:+PrintCompilation 选项一致。
# jinfo:Java 配置信息工具
用法:
jinfo [option] pid
Options:
option 选项内容:
-flag name:打印指定命令行标志的名称和值。
-flag[ +| -] name:启用或禁用指定的命令行标志。
-flag name=value:将指定的命令行标志设置为指定的值。
-flags:打印传递给 JVM 的命令行标志。
-sysprops:将 Java 系统属性打印为名称/值对。
示例:jinfo -flags 18650
# jmap:指定进程的详细信息
用法:
jmap [options] pid
Options:
option 选项内容:
-clstats pid: 连接到正在运行的进程并打印 Java 堆的类加载器统计信息。
-finalizerinfo pid: 连接到正在运行的进程,并在等待完成的对象上打印信息。
-histo[:live] pid: 连接到正在运行的进程,并打印 Java 对象堆的直方图。如果 live 指定了子选项,则它仅计算活动对象。
-dump:dump_options pid: 连接到正在运行的进程并转储 Java 堆。该 dump_options 包括:
live --- 指定时,仅转储活动对象;如果未指定,则转储堆中的所有对象。
format=b --- 以 hprof 二进制格式转储 Java 堆
file=filename --- filename-将堆转储到 filename
示例:jmap -dump:live,format=b,file=heap.bin pid
dump 文件太大时请注意,为了保证 dump 的信息是可靠的,所以会暂停应用程序。对于 dump 文件分析推荐使用 jprofiler (opens new window) 工具进行分析。
如果 jmap 添加了 :live 参数后,JVM 会先触发 gc,然后再统计信息。
# jstack:Java 堆栈跟踪工具
jstack (opens new window) 命令显示指定 Java 进程的 Java 线程的 Java 堆栈跟踪。对于每个 Java 框架,将打印完整的类名,方法名,字节码索引(BCI)和行号(如果有)。
用法:
jstack [options] pid
Options:
option 选项内容:
- -l: 长列表选项显示有关锁的其他信息。
示例:jstack -l pid
# jcmd:诊断命令
jcmd (opens new window) - 将诊断命令请求发送到正在运行的 Java 虚拟机(JVM)
用法:
jcmd <pid | main class> <command ...|PerfCounter.print|-f file>
实用程序会将诊断命令请求发送到 Java 进程的进程 ID。jcmd -l
说明:jcmd
不使用参数与使用相同jcmd -l
Options:
-f:从文件读取并执行命令
-l:显示不在单独的 docker 进程中运行的 Java 虚拟机进程标识符的列表,以及用于启动该进程的主类和命令行参数。如果 JVM 在 docker 进程中,则必须使用诸如 ps 查找 PID 的工具。
通过jcmd pid help
查看其支持的命令列表;
$jcmd 18650 help
The following commands are available:
Compiler.CodeHeap_Analytics
Compiler.codecache --- 打印代码缓存的布局和边界
Compiler.codelist --- 打印代码缓存中所有仍在运行的已编译方法
Compiler.directives_add --- 从文件添加编译器指令
Compiler.directives_clear --- 删除所有编译器指令
Compiler.directives_print --- 打印所有活动的编译器指令
Compiler.directives_remove --- 删除最新添加的编译器指令
Compiler.queue --- 打印排队等待编译的方法
GC.class_histogram --- 提供有关 Java 堆使用情况的统计信息
GC.class_stats --- 提供有关 Java 类元数据的统计信息
GC.finalizer_info --- 提供有关 Java 完成队列的信息
GC.heap_dump --- 生成 Java 堆的 HPROF 格式转储
GC.heap_info --- 提供通用的 Java 堆信息
GC.run --- java.lang.System.gc
GC.run_finalization --- java.lang.System.runFinalization
JFR.check
JFR.configure
JFR.dump
JFR.start
JFR.stop
JVMTI.agent_load --- 加载 JVMTI 本机代理
JVMTI.data_dump --- 通知 JVM 对 JVMTI 进行数据转储请求
ManagementAgent.start
ManagementAgent.start_local
ManagementAgent.status
ManagementAgent.stop
Thread.print --- 打印所有带有堆栈跟踪的线程
VM.class_hierarchy --- 打印所有已加载类的列表,缩进以显示类层次结构
VM.classloader_stats --- 打印有关所有 ClassLoader 的统计信息。
VM.classloaders
VM.command_line --- 打印用于启动此 VM 实例的命令行
VM.dynlibs --- 打印加载的动态库
VM.flags --- 打印 VM 标志选项及其当前值
VM.info --- 打印有关 JVM 环境和状态的信息
VM.log --- 列出当前日志配置,启用/禁用/配置日志输出,或旋转所有日志
VM.metaspace
VM.native_memory --- 打印本机内存使用情况
VM.print_touched_methods --- 打印此 JVM 生命周期内曾经接触过的所有方法
VM.set_flag --- 使用提供的值设置 VM 标志选项
VM.start_java_debugging
VM.stringtable --- 转储字符串表
VM.symboltable --- 转储符号表
VM.system_properties --- 打印系统属性
VM.systemdictionary --- 打印字典哈希表大小和存储桶长度的统计信息
VM.uptime --- 打印虚拟机正常运行时间
VM.version --- 打印 JVM 版本信息
help
如果想查看命令的选项,比如想查看 VM.commercial_features 命令选项,可以通过如下命令:
$ jcmd 18650 help VM.native_memory
18650:
VM.native_memory
Print native memory usage
Impact: Medium
Permission: java.lang.management.ManagementPermission(monitor)
Syntax : VM.native_memory [options]
Options: (options must be specified using the <key> or <key>=<value> syntax)
summary : [optional] request runtime to report current memory summary, which includes total reserved and committed memory, along with memory usage summary by each subsytem. (BOOLEAN, false)
detail : [optional] request runtime to report memory allocation >= 1K by each callsite. (BOOLEAN, false)
baseline : [optional] request runtime to baseline current memory usage, so it can be compared against in later time. (BOOLEAN, false)
summary.diff : [optional] request runtime to report memory summary comparison against previous baseline. (BOOLEAN, false)
detail.diff : [optional] request runtime to report memory detail comparison against previous baseline, which shows the memory allocation activities at different callsites. (BOOLEAN, false)
shutdown : [optional] request runtime to shutdown itself and free the memory used by runtime. (BOOLEAN, false)
statistics : [optional] print tracker statistics for tuning purpose. (BOOLEAN, false)
scale : [optional] Memory usage in which scale, KB, MB or GB (STRING, KB)
常用命令:
jcmd pid Thread.print -l # 打印线程栈
jcmd pid VM.command_line # 打印启动命令及参数
jcmd pid GC.heap_dump /data/31275.dump # 生成 Java 堆的 HPROF 格式转储
jcmd pid GC.class_histogram #查看类的统计信息
jcmd pid VM.system_properties #查看系统属性内容
jcmd pid VM.uptime #查看虚拟机启动时间
jcmd pid PerfCounter.print #查看性能统计
# 命令总结
# 所有平台
jaotc --- 为编译的 Java 方法生成本机代码的 Java 静态编译器
jar --- 创建和管理 JAR 文件
jarsigner --- 签名并验证 Java 存档(JAR)文件
java --- 启动 java 应用程序,用于运行 class 文件或者 JAR 文件
javac --- 用于编译 Java 语言的编译器
javadoc --- 从 Java 源文件生成 API 文档的 HTML 页面
javap --- Java 字节码分析工具
jcmd --- 向正在运行的 Java 虚拟机(JVM)发送诊断命令请求
jconsole --- 启动图形控制台来监视和管理 Java 应用程序
jdb --- 基于 JPDA 协议的调试器,以类似 GDB 的方式调试 java 代码
jdepscan --- 静态分析工具,用于扫描 jar 文件(或类文件的某些其他聚合)废弃的类,JDK 9 开始提供
jdeps --- 启动 Java 类依赖分析器
jfr --- 解析并打印飞行记录器文件
jhsdb --- 附加到 Java 进程或启动后期调试器以分析崩溃的 Java 虚拟机(JVM)的核心转储的内容
jinfo --- 为指定的 Java 进程生成 Java 配置信息
jjs --- 调用 Nashorn 引擎的命令行工具
jlink --- 将一组模块及其依赖项组装并优化到自定义运行时映像中
jmap --- 打印指定进程的详细信息
JMOD --- 创建 JMOD 文件并列出现有的 JMOD 文件的内容
jps --- 显示目标系统上的 JVM 的 Java 进程信息
jrunscript --- 运行支持交互和批处理模式的命令行脚本 shell
jshell --- 在 read eval print 循环(REPL)中交互式地计算 Java 编程语言的声明、语句和表达式
jstack --- 打印指定 Java 进程的 Java 线程的 Java 堆栈跟踪
jstat --- 监视 JVM 统计信息
jstatd --- 监测 JVM 的创建和终止,并提供一个接口,允许远程监测工具附加到运行于本地主机的 JVM 上
keytool --- 密钥和证书管理工具,主要用于密钥和证书的创建、修改、删除等
pack200 --- 使用 Java gzip 压缩程序将 Java 存档(JAR)文件转换为压缩的 pack200 文件,对普通 JAR 文件进行高效压缩,以便于能够更快地进行网络传输
rmic --- Java RMI 编译器,为使用 JRMP 或 IIOP 协议的远程对象生成 stub、skeleton、和 tie 类,也用于生成 OMG IDL
rmid --- Java RMI 激活系统守护进程,rmid 启动激活系统守护进程,允许在虚拟机中注册或激活对象
rmiregistry --- Java 远程对象注册表,用于在当前主机的指定端口上创建并启动一个远程对象注册表
serialver --- 序列版本命令,用于生成并返回 serialVersionUID。
unpack200 --- JAR 文件解压工具,将一个由 pack200 打包的文件解压提取为 JAR 文件
# 仅 Windows 平台
jabswitch --- 启用或禁用 Java 访问桥
jaccessinspector --- 使用 Java 辅助工具 API 检查关于 Java 虚拟机中对象的可访问信息
jaccesswalker --- 浏览特定 Java 虚拟机中的组件树,并在树视图中显示层次结构
javaw --- 在没有控制台窗口的情况下启动 Java 应用程序
kinit --- 主要用于获取或缓存 Kerberos 协议的票据授权票据
klist --- 允许用户查看本地凭据缓存和密钥表中的条目 (用于 Kerberos 协议)
ktab-Kerberos --- 密钥表管理工具,允许用户管理存储于本地密钥表中的主要名称和服务密钥
# 参考
- Java® Development Kit Version 13 Tool Specifications (opens new window)
- 《深入理解 Java 虚拟机:JVM 高级特性与最佳实践(第 3 版)》周志明 著