前言

此博文以jdk11中bin命令为准,旧版本被移除的命令不再介绍
jdk的bin目录下面有许多命令,可以很方便的堆虚拟机进行监控或者故障排查等
8. JDK内置的常用工具使用大全 - 图1
bin目录下的命令本质上都是Tools.jar的一层封装,首先对比一下常用的命令功能

bin目录命令名称 功能描述
jshell 类似于python控制台的,直接运行java代码,而不必编写class和main,java9之后出现
java Java运行工具,用于运行.class字节码文件或.jar文件
javac Java编译工具(Java Compiler),用于编译Java源代码文件。
javadoc Java文档工具,主要用于根据Java源代码中的注释信息生成HTML格式的API帮助文档
javap Java反编译工具,主要用于根据Java字节码文件反汇编为Java源代码文件。
jcmd Java 命令行(Java Command),用于向正在运行的JVM发送诊断命令请求。
jconsole 图形化用户界面的监测工具,主要用于监测并显示运行于Java平台上的应用程序的性能和资源占用等信息。
jdb Java调试工具(Java Debugger),主要用于对Java应用进行断点调试。
jhsdb 进程外的调试工具,主要从虚拟机中获取运行信息
jimage 浏览JIMAGE文件的内容
jlink 可以创建自己的自定义 JRE
jmod 可以创建自己的自定义 JRE
jpackage 可以创建自己的自定义 JRE
jhat Java堆分析工具(Java Heap Analysis Tool),用于分析Java堆内存中的对象信息。
jinfo Java配置信息工具(Java Configuration Information),用于打印指定Java进程、核心文件或远程调试服务器的配置信息。
jmap Java内存映射工具(Java Memory Map),主要用于打印指定Java进程、核心文件或远程调试服务器的共享对象内存映射或堆内存细节
jmc Java任务控制工具(Java Mission Control),主要用于HotSpot JVM的生产时间监测、分析、诊断。
jps JVM进程状态工具(JVM Process Status Tool),用于显示目标系统上的HotSpot JVM的Java进程信息。
jrunscript Java命令行脚本外壳工具(command line script shell),主要用于解释执行javascript、groovy、ruby等脚本语言。
jstack Java堆栈跟踪工具,主要用于打印指定Java进程、核心文件或远程调试服务器的Java线程的堆栈跟踪信息。
jstat JVM统计监测工具(JVM Statistics Monitoring Tool),主要用于监测并显示JVM的性能统计信息。
jstatd jstatd(VM jstatd Daemon)工具是一个RMI服务器应用,用于监测HotSpot JVM的创建和终止,并提供一个接口,允许远程监测工具附加到运行于本地主机的JVM上。
jvisualvm JVM监测、故障排除、分析工具,主要以图形化界面的方式提供运行于指定虚拟机的Java应用程序的详细信息。
keytool 管理密钥库和证书
kinit 用于获得和缓存网络认证协议Kerberos 票证的授予票证
ktab 密钥和证书管理工具
rmid Java远程方法调用(RMI:Remote Method Invocation)活化系统守护进程
rmiregistry Java远程对象注册表
serialver 返回类的 serialVersionUID序列化id

jshell

如果你想测试一段简单的代码,在java9中,就不必再打开编译器,再写个main方法运行了,可以直接使用jshell
8. JDK内置的常用工具使用大全 - 图2
8. JDK内置的常用工具使用大全 - 图3
常用命令:
8. JDK内置的常用工具使用大全 - 图4
/reset : 清空所有代码
/list: 列出之前写的代码
/history: 列出历史命令
/methods: 列出已声明的方法
/edit: 打开新面板编辑代码:
8. JDK内置的常用工具使用大全 - 图5
/drop: 删除,可跟行数或者方法名进行删除
保存与导入:
8. JDK内置的常用工具使用大全 - 图6

java

我们一般启用一个springBoot jar项目会直接使用java -jar,但是java工具还有很多其他的功能:
java -jar Hello.jar 启动jar包
还可以后面跟参数,添加或者覆盖原有参数:
springboot方式: java -jar demo.jar —spring.profiles.active=dev —server.port=8181
-D方式: java -jar demo.jar -Dspring.profiles.active=dev -Dserver.port=8181
后台运行: nohup java -jar xxx.jar —server.port=81 &
java -cp lib/;etc/ com.Start param1 param2 指定启动的jar包的主类,可以添加需要的配置文件和jar包,支持通配符将lib下的所有jar文件以及etc下的所有配置文件添加到 classpath 中
注意:jar包匹配使用_, 配置文件使用目录/,多个window上分号“;” linux上分号“:”

javadoc

javadoc 命令可以将java代码中的注释和说明信息,生成并输出到HTML文件中
命令: javadoc -d -version -author -d 文档存放目录 源文件名.java 注意要配置编码,如果是中文
-version -author 包含这两个注解的信息
例如: 注释一个类:
8. JDK内置的常用工具使用大全 - 图7
8. JDK内置的常用工具使用大全 - 图8
使用javadoc生成:
8. JDK内置的常用工具使用大全 - 图9
8. JDK内置的常用工具使用大全 - 图10
也可以直接使用idea生成javadoc,注意要设置编码,其实也是执行的javadoc命令:
8. JDK内置的常用工具使用大全 - 图11
8. JDK内置的常用工具使用大全 - 图12
注意设置编码直接用 -encoding UT-8, 空格就可以,不能用= ,javadoc生成包含了非常多的选项,可以在命令-help查看功能:

javap

javap是jdk自带的反解析工具。它的作用就是根据class字节码文件,反解析出当前类对应的code区(汇编指令)、本地变量表、异常表和代码行偏移量映射表、常量池等等信息。
通过反编译生成的汇编代码,我们可以深入的了解java代码的工作机制,当然了还有更好用的反编译工具和idea,使用:
java -选项 class文件
一般使用的是-v -l -c三个选项:
javap -v classxx,不仅会输出行号、本地变量表信息、反编译汇编代码,还会输出当前类用到的常量池等信息。
javap -l 会输出行号和本地变量表信息。
javap -c 会对当前class字节码进行反编译生成汇编代码。
反汇编后的文件:
8. JDK内置的常用工具使用大全 - 图13

jcmd

在JDK 1.7之后,新增了一个命令行工具jcmd,可以替代jps,jinfo,jstat,jmap等命令的全能型工具,并且在jdk9和11中不断的加强了此工具,他有统一其他所有工具的趋势(图形工具除外)

功能 jcmd 类似工具
列出jcmd支持命令 jcmd pid help
列出java进程 jcmd jps -l
堆转储文件 jcmd pid GC.heap_dump name.bin jmap -dump
堆对象统计信息 jcmd pid GC.class_histogram jmap -histo
线程转储 jcmd pid Thread.print jstack
列出系统属性 jcmd pid VM.system_properties jinfo -sysprops
列出VM参数,-X 和 -XX jcmd pid VM.flags jinfo -flags
虚拟机启动时间 jcmd pid VM.uptime
列出所有性能相关数据 jcmd pid PerfCounter.print
列出加载的类层次结构 jcmd pid VM.class_hierarchy
列出启动命令(-D) jcmd pid VM.command_line
列出java进程信息 jcmd pid VM.info
执行垃圾回收 jcmd pid GC.run System.gc(),但不确定会马上执行
列出被加载类的更详细信 jcmd pid GC.class_stats java9之前需要开启参数-XX:+UnlockDiagnosticVMOptions
进行内存追踪 jcmd pid VM.native_memory java9之前需要开启参数-XX:NativeMemoryTracking=summary

这里列举三个比较有意思的功能:

1 jcmd pid GC.class_histogram

堆对象直方图,可以很直观的看到每个类产生了多少个实例,以及这些实例共占用了多少内存:
8. JDK内置的常用工具使用大全 - 图14

2 jcmd pid GC.class_stats

GC.class_stats相比GC.class_histogram之外,能够提供被加载类的更详细信息,借助它,我们能够看到Metaspace每个类所占据的空间 ,看到每个类的实例所占用多少内存
不过注意: GC.class_stats是一个高开销的诊断命令,它运行在全局SafePoint(STW暂停)中。对VM有很大影响
除其他外,此操作遍历整个堆来计算所有加载类的所有实例占用的内存 ,已被移除在JDK 15。
8. JDK内置的常用工具使用大全 - 图15
加载类的名称(ClassName)、每个类所占据的字节(KlassBytes)、每个类的实例所占据的字节(InstBytes)、每个类中方法的数量(MethodCount)、字节码所占据的空间(ByteCodes))等

3 jcmd VM.native_memory

java8给HotSpot VM引入了Native Memory Tracking (NMT)特性,可以用于追踪JVM的内部内存使用情况
可以利用jcmd(jdk自带)这个工具来访问NMT的数据
NMT必须先通过VM启动参数中打开,不过要注意的是,打开NMT会带来5%-10%的性能损耗。
-XX:NativeMemoryTracking=[off | summary | detail] off: 默认关闭 summary: 只统计各个分类的内存使用情况. detail: Collect memory usage by individual call sites.
命令使用:
jcmd VM.native_memory [summary | detail | baseline | summary.diff | detail.diff | shutdown] [scale= KB | MB | GB] # summary: 分类内存使用情况. # detail: 详细内存使用情况,除了summary信息之外还包含了虚拟内存使用情况。 # baseline: 创建内存使用快照,方便和后面做对比 # summary.diff: 和上一次baseline的summary对比,需要先打个基线 # detail.diff: 和上一次baseline的detail对比,需要先打个基线 # shutdown: 关闭NMT
演示:
1 先打基线,如果不对比,也可以不打:
8. JDK内置的常用工具使用大全 - 图16
2 然后查看内存使用信息:
jcmd VM.native_memory summary scale=MB 可换算单位
8. JDK内置的常用工具使用大全 - 图17
3 可以和基线时刻进行对比:
8. JDK内置的常用工具使用大全 - 图18
4 输出NMT信息解释:
8. JDK内置的常用工具使用大全 - 图19

jconsole

jconsole是JDK内置的图形化Java性能分析工具,可以在命令行运行。启动可以更具Java进程id查看程序的堆使用,线程情况,类信息等。
8. JDK内置的常用工具使用大全 - 图20
8. JDK内置的常用工具使用大全 - 图21

jhsdb

jhsdbshi JDK 9用于处理性能和可维护性问题的新命令行工具: jhsdb,如果附加到进程,则会导致进程挂起,此命令jdk版本必须和项目保持一致
jhsdb有几种模式,下面简单介绍一下:
所有模式的部分参数:
—pid 挂起进程的进程ID。
—exe 可执行文件名。
—core 核心转储文件名。
—help 显示该命令可用的选项。

jhsdb hsdb模式

启动交互式GUI调试器。可以在GUI界面进行查找信息等操作
8. JDK内置的常用工具使用大全 - 图22
还有其他两种debug模式,这里就不说了

jhsdb jstack模式

1 jhsdb jstack —locks —pid 6893 : 检测死锁信息以及打印锁的信息,
我这里程序模拟了一个死锁,检测结果,后续会继续打印所有锁的信息:
8. JDK内置的常用工具使用大全 - 图23

jhsdb jmap模式

jhsdb的jmap模式提供的功能跟jmap和jcmd命令提供的功能一样。 这些包括堆转储( —heap ),类直方图( —histo ),类加载器统计( —clstats ),和释放信息( —finalizerinfo )
例如: jhsdb jmap —histo —pid 844
8. JDK内置的常用工具使用大全 - 图24

jhsdb jinfo模式

打印基本的JVM信息。此模式和 jinfo以及jcmd命令功能也是一样的,这里不再赘述

jhsdb jsnap模式

jhsdb jsnap —pid 844
打印性能计数器信息。包含启动的线程数,启动参数等等一些信息
8. JDK内置的常用工具使用大全 - 图25

jimage

java9提供了新的打包格式jimage,而不再使用jar这种文件格式打包
jar是一个非常老的协议,它是基于很老的zip协议,效率上比较差,空间占用也比较大。
jar是基于文件系统而不是基于module的,也就是说jar打包的原则是把某几个目录下的文件打成一个包
java9模块化之后,就需要一种能通过模块直接加载class的方式,格式针对空间和速度进行了优化,这里简单介绍一下jimage:
8. JDK内置的常用工具使用大全 - 图26
jimage工具可以解压jimage格式文件,以及打印jimage包的头部信息,以及模块列表等


jlink

Jlink是Java的新命令行工具,用于将一系列模块聚合、优化,打包到一个自定义的jre镜像中,
默认JRE的大小为203 MB。为了执行简单的很少的代码,必须在计算机中维护203 MB的JRE。这完全是浪费内存
有了jlink,就可以创建我们需要的jre,只包含我们需要的类,从而减少内存,提高性能,这就更适合开发物联网和微服务

jmod(暂无)

jpackage(暂无)

jdb(暂无)

jhat

用于分析heapdump文件,它会建立一个HTTP/HTML服务器,让用户可以在浏览器上查看分析结果,一般与jmap搭配使用,
不过功能比较简陋,一般使用其他工具来分析dump文件,比如:Eclipse MAT,Yourkit等
8. JDK内置的常用工具使用大全 - 图27
“Server is ready.”出现后就可以在浏览器中键入http://localhost:7000 查看分析结果了, 此功能在jdk11之后已被移除

jinfo

主要用于打印配置信息,包括命令行参数、系统变量。极少数的情况下,我们可以用其来修改命令行参数
没有选项直接打印虚拟机参数和系统参数
jinfo -flags 进程号: 打印虚拟机参数
jinfo -sysprops 进程号: 打印系统变量
jinfo -flag +- 进程号:开启或者关闭虚拟机参数
8. JDK内置的常用工具使用大全 - 图28
观察运行中的java程序的运行环境参数:参数包括Java System属性和JVM命令行参数、也可以设置参数的值,并使之立即生效。
8. JDK内置的常用工具使用大全 - 图29
8. JDK内置的常用工具使用大全 - 图30

jmap

jmap可以生成 java 程序的 dump 文件, 也可以查看堆内对象示例的统计信息、查看 ClassLoader 的信息以及 finalizer 队列
-dump: 生成堆转储快照
8. JDK内置的常用工具使用大全 - 图31
-histo 显示堆中对象的统计信息:
冷知识:一个最简单的springboot项目初始化会创建26万多个对象(String就有四万多个),总共2780个类
添加live只统计活着的对象
8. JDK内置的常用工具使用大全 - 图32
8. JDK内置的常用工具使用大全 - 图33
-clstats: 打印类加载器信息
8. JDK内置的常用工具使用大全 - 图34
-finalizerinfo 打印等待回收的对象信息
8. JDK内置的常用工具使用大全 - 图35
-heap :打印heap堆的概要信息,GC使用的算法,heap的配置及wise heap的使用情况 |
8. JDK内置的常用工具使用大全 - 图36
可以生成java应用程序的堆快照和对象统计信息。
下面的命令可以看到java进程中某一时刻的类示例数量以及所占的字节数。
打印进程的类加载器和类加载器加载的持久代对象信息,输出:类加载器名称、对象是否存活(不可靠)、对象地址、父类加载器、已加载的类大小等信息。

1、使用jmap -heap pid查看进程堆内存使用情况,包括使用的GC算法、堆配置参数和各代中堆内存使用情况。

2、使用jmap -histo[:live] pid 查看堆内存中的对象数目、大小统计直方图,如果带上live则只统计活对象

8. JDK内置的常用工具使用大全 - 图37
也可以将当前程序的堆快照导出到文件中:
8. JDK内置的常用工具使用大全 - 图38

jmc(暂无)

jps

列出正在运行的JVM虚拟机进程并显示主类和进程id等信息
8. JDK内置的常用工具使用大全 - 图39
常用的参数:
-l 输出Java应用程序的main class的完整包
-q 仅显示pid,不显示其它任何相关信息
-m 输出传递给main方法的参数
-v 输出传递给JVM的参数。在诊断JVM相关问题的时候,这个参数可以查看JVM相关参数的设置

注:这个命令相信大多数java程序员都知晓、查找当前运行的java进程、当需要kill掉某个进程的时候可以用到。

  1. bogon:~ chengluchao$ jps -l
  2. 14064 org.jetbrains.idea.maven.server.RemoteMavenServer
  3. 14049
  4. 14082 org.jetbrains.jps.cmdline.Launcher
  5. 5036 com.baiwang.UserServiceApplication
  6. 14095 jdk.jcmd/sun.tools.jps.Jps

jrunscript(暂无)

jsadebugd(暂无)

jstack

java堆栈跟踪工具,用于生成当前时刻虚拟机内每一条线程正在执行的方法堆栈集合,以定位线程出现长时间停顿原因
jstack -l pid:
8. JDK内置的常用工具使用大全 - 图40
可以用来查看java应用程序的堆栈信息。
jstack -l
可以用来查看进程中线程状态,检测死锁等。

jstack可以定位到线程堆栈,根据堆栈信息可以定位到具体代码,所以它在JVM性能调优中使用得非常多。下面我们来一个实例找出某个Java进程中最耗费CPU的Java线程并定位堆栈信息,用到的命令有ps、top、printf、jstack、grep。

1.:先找出Java进程ID,我部署在服务器上的Java应用名称为mrf-center:
ps -ef | grep mrf -center | grep -v grep
8. JDK内置的常用工具使用大全 - 图41

得到进程ID为21711

2.:找出该进程内最耗费CPU的线程 top -Hp pid
8. JDK内置的常用工具使用大全 - 图42
TIME列就是各个Java线程耗费的CPU时间,CPU时间最长的是线程ID为21742的线程
printf”%x “21742得到21742的十六进制值为54ee,下面会用到。

3.:jstack上场、它用来输出进程21711的堆栈信息,然后根据线程ID的十六进制值grep,如下:
8. JDK内置的常用工具使用大全 - 图43

jstat

jstat可以显示本地或远程虚拟机进程中的类装载、内存、垃圾收集情况、JIT编译等运行数据
格式: jstat 选项 进程ID 间隔时间(毫秒) 查询次数:
8. JDK内置的常用工具使用大全 - 图44
8. JDK内置的常用工具使用大全 - 图45
其他参数:
8. JDK内置的常用工具使用大全 - 图46
jstat [ generalOption | outputOptions vmid [interval[s|ms] [count]] ] ,可以用来查看堆信息,垃圾回收信息等,详细使用命令可以通过man jstat命令来查看。
8. JDK内置的常用工具使用大全 - 图47
查看垃圾回收信息
8. JDK内置的常用工具使用大全 - 图48
S0C:年轻代中第一个survivor(幸存区)的容量 (字节)
S1C:年轻代中第二个survivor(幸存区)的容量 (字节)
S0U:年轻代中第一个survivor(幸存区)目前已使用空间 (字节)
S1U:年轻代中第二个survivor(幸存区)目前已使用空间 (字节)
EC:年轻代中Eden(伊甸园)的容量 (字节)
EU:年轻代中Eden(伊甸园)目前已使用空间 (字节)
OC:Old代的容量 (字节)
OU:Old代目前已使用空间 (字节)
PC:Perm(持久代)的容量 (字节)
PU:Perm(持久代)目前已使用空间 (字节)
YGC:从应用程序启动到采样时年轻代中gc次数
YGCT:从应用程序启动到采样时年轻代中gc所用时间(s)
FGC:从应用程序启动到采样时old代(全gc)gc次数
FGCT:从应用程序启动到采样时old代(全gc)gc所用时间(s)
GCT:从应用程序启动到采样时gc用的总时间(s)
NGCMN:年轻代(young)中初始化(最小)的大小 (字节)
NGCMX:年轻代(young)的最大容量 (字节)
NGC:年轻代(young)中当前的容量 (字节)
OGCMN:old代中初始化(最小)的大小 (字节)
OGCMX:old代的最大容量 (字节)
OGC:old代当前新生成的容量 (字节)
PGCMN:perm代中初始化(最小)的大小 (字节)
PGCMX:perm代的最大容量 (字节)
PGC:perm代当前新生成的容量 (字节)
S0:年轻代中第一个survivor(幸存区)已使用的占当前容量百分比
S1:年轻代中第二个survivor(幸存区)已使用的占当前容量百分比
E:年轻代中Eden(伊甸园)已使用的占当前容量百分比
O:old代已使用的占当前容量百分比
P:perm代已使用的占当前容量百分比
S0CMX:年轻代中第一个survivor(幸存区)的最大容量 (字节)
S1CMX :年轻代中第二个survivor(幸存区)的最大容量 (字节)
ECMX:年轻代中Eden(伊甸园)的最大容量 (字节)
DSS:当前需要survivor(幸存区)的容量 (字节)(Eden区已满)
TT: 持有次数限制
MTT : 最大持有次数限制

jstatd(暂无)

jvisualvm

此命令JDK9之后就被移除了,不过可以在官网下载
需要在项目启动的时候添加对应参数:

  1. # 远程服务器ip,对应的端口,是否使用SSL和权限验证等
  2. -Djava.rmi.server.hostname=192.168.120.30 -Dcom.sun.management.jmxremote.port=9528 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false

新建JMX连接,
8. JDK内置的常用工具使用大全 - 图49
监控效果如图,还可以查jvm参数信息,线程情况等:
8. JDK内置的常用工具使用大全 - 图50

keytool(暂无)

kinit(暂无)

ktab(暂无)

rmid(暂无)

rmiregistry(暂无)

serialver(暂无)

GC日志

打印日志详细信息
8. JDK内置的常用工具使用大全 - 图51