经常使用适当的虚拟机监控和分析工具可以加快分析数据、定位解决问题的速度
本文介绍JDK的bin目录内的部分工具作用
概述
名称 | 作用 |
---|---|
jps | JVM Process Status Tool,显示指定系统内所有的HotSpot虚拟机进行 |
jstat | JVM Statistics Monitoring Tool,用于收集HotSpot虚拟机个方面的运行数据 |
jinfo | Configuration Info for Java,显示虚拟机配置信息 |
jmap | Memory Map for Java,生成虚拟机的内存转储快照(heapdump文件) |
jstack | Stack Trace for Java,显示虚拟机的线程快照 |
jps
功能
- 列出正在运行的虚拟机进程
- 显示虚拟机执行主类(Main Class , main()函数所在的类)名称
- 进程的本地虚拟机唯一ID(Local Virtual Machine Identifier,LVMID)
当启动多个虚拟机进程,无法根据进程名称定位时,那就需要JPS命令显示主类的功能才能区分。
用法
jps [options] [hostid]
jps可以通过RMI协议开启了RMI服务的远程虚拟机进程状态,hostid
为RMI注册表中注册的主机名。
RMI:
概念
Java远程方法调用,即Java Remote Method Invocation,是用于实现远程过程调用的应用编程接口。
它使客户急上运行的程序可以调用远程服务器上的对象,能够在网络环境中分布操作。宗旨是尽可能简化远程接口对象的使用。
使用
依赖于接口。在需要创建一个远程对象的时候,通过传递一个接口来隐藏底层的实现细节。客户端得到的远程对象句柄正好与本地的根代码链接,由后者负责透过网络通信。这样一来,只需关系如何通过自己的接口句柄发送消息。
实现方式
- 使用JRMP(Java Remote Message Protocol,Java远程消息交换协议)
- 与CORBA兼容
包名
java.rmi
与RPC的区别
- 定义
- RMI:Java分布式框架
- RPC:网络协议
- 方法调用方式不同
- 对RMI来说,如果一个方法在服务器上执行,但是没有相匹配的签名被添加到这个远程接口上,那么这个新方法就不能被RMI客户方所调用
- RPC是通过网络服务协议向远程主机发送请求。
- 适用语言不通
- RMI只用于Java
- RPC是网络服务协议,与操作系统和语言无关
- 传递信息的限制
- RMI的调用结果可以是对象类型或者基本数据类型
- RPC不允许传递对象,结果统一由外部数据表示(External Data Representation,XDR)语言表示,这种语言抽象了字节序列和数据类型结构之间的差异
- 发现不匹配的方法
- RMI在程序开发过程中因为对象或方法不匹配造成的错误可以在编译期发现
- RPC在运行期发现
- 协议
- RMI:TCP/IP
- RPC:UDP
常用参数
属性 | 作用 |
---|---|
-p | 只输出LVMID,省略主类的名称 |
-m | 输出虚拟机进程启动时传递给主类main()函数的参数 |
-l | 输出主类的全名,如果进程执行的是jar包,输出jar路径 |
-v | 输出虚拟机进程启动时JVM参数 |
jstat
功能
- 监视虚拟机各种运行状态信息
- 类装载
- 内存
- 垃圾回收
- JIT编译
- 等运行时数据
运行时定位虚拟机性能问题的首选工具
用法
jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]
- -option
option | displays |
---|---|
-class | 类加载情况 |
-compiler | HotSpot中即时编译器编译情况 |
-gc | JVM中堆的垃圾收集情况 |
-gccapacity | 存储容量、垃圾收集情况 |
-gccause | 垃圾收集的原因 |
-gcmetacapacity | metasapce的存储容量 |
-gcnew | 新生代的垃圾收集情况 |
-gcnewcapacity | 新生代的存储容量 |
-gcold | 老年代及持久代发生GC的情况 |
-gcoldcapacity | 老年代的存储容量 |
-gcutil | 垃圾收集的情况 |
-printcompilation | HotSpot编译方法的统计 |
- -t
- 显示从虚拟机启动在当前时间的间隔
- 单位:秒
- -h
- 每隔n行显示表头
- vmid
- 本地:VMID和LVMID一致
- 远程:
[protocol:][//] lvmid[@hostname[:port]/servername]
- interval
- 查询的间隔
- 不写则查询一次
- 例:
1s
,1秒显示一次;500
,500毫秒查询一次
- count
- 查询的次数
- 不写则查询一次
- 例:
20
,总共显示20次
示例
jstat -gc -h 5 -t 1748 1s 20
表头
版本:JDK9
表头 | 描述 |
---|---|
S0C | 新生代中Survivor space中S0当前容量的大小(KB) |
S1C | 新生代中Survivor space中S1当前容量的大小(KB) |
S0U | 新生代中Survivor space中S0容量使用的大小(KB) |
S1U | 新生代中Survivor space中S1容量使用的大小(KB) |
EC | Eden space当前容量的大小(KB) |
EU | Eden space容量使用的大小(KB) |
OC | Old space当前容量的大小(KB) |
OU | Old space使用容量的大小(KB) |
MC | metaspace当前容量的大小(KB) |
MU | metaspace 使用容量的大小(KB) |
CCSC | 压缩类空间当前容量大小(KB) |
CCSU | 压缩类空间使用容量大小(KB) |
YGC | 从应用程序启动到采样时发生 Young GC 的次数 |
YGCT | 从应用程序启动到采样时 Young GC 所用的时间(秒) |
FGC | 从应用程序启动到采样时发生 Full GC 的次数 |
FGCT | 从应用程序启动到采样时 Full GC 所用的时间(秒) |
GCT | 从jvm启动到采样时用于垃圾回收的总时间(单位秒),它的值等于YGC+FGC |
jinfo
功能
- 实时查看和调整虚拟机的各项参数
用法
查看:
- 概览:
jinfo [option] pid
- 指定参数名称:
jinfo -flag name pid
- 查看JVM flag:
jinfo -flags pid
- 查看Java系统属性:
jinfo -sysprops pid
修改:
jinfo -flag [+/-]name pid
jinfo -flag name=value
示例
java -XX:+PrintFlagsFinal -version|grep manageable
查看JVM中哪些flag可以被jinfo动态修改
jmap
功能
- 生成堆转储快照(heapdump),就是打印内存内的所有“对象”的情况
- 查询finalize执行队列
- Java堆和永久代的详细信息
- 空间使用率
- 当前用的是哪种收集器
- 等等
用法
jmap [options] pid
- option
参数 | 说明 |
---|---|
-clstats | 打印堆中的classload信息。包含每个classload的名字、活跃性、地址、父classloader和加载的class数量 |
-finalizerinfo | 打印在F-Queue中等待Finalizer线程执行finalize方法的对象信息 |
-histo[:live] | 打印堆中每个class的实例数目、内存占用、类全名信息。VM的内部类名字开头会加上前缀“*”。如果live子参数加上后,只统计活的对象数量 |
-dump: |
生成Java堆转储快照 |
- dump-options
参数 | 说明 |
---|---|
live | 写了只统计存活的对象,没写则统计所有 |
format=b | 二进制格式 |
file=filename | 转储到指定文件 |
示例
jmap -dump:live,format=b,file=heap.hprof pid
jhat
JDK9中被移除,使用jvisualvm、Eclipse Memory Analyzer、IBM HeapAnalyzer等工具来分析dump文件。
另:IBM HeapAnalyzer用于分析IBM J9虚拟机生成的映像文件,各个虚拟机产生的文件格式不一致,所以分析工具也不能通用。
jstack
功能
- 用于生成虚拟机当前时刻的线程快照
- 一般称为threaddump或者javacore文件
线程快照:当前虚拟机内每一条线程正在执行的方法堆栈的集合。
目的:定位线程出现长时间停顿的原因,如死锁、死循环、请求外部资源导致的长时间等待之类原因。
用法
jstack [option] pid
- option
参数 | 说明 |
---|---|
-l | 除堆栈外,显示关于锁的附加信息。 例如属于java.util.concurrent的ownable synchronizers列表. |
示例
jstack -l pid