前言
此博文以jdk11中bin命令为准,旧版本被移除的命令不再介绍
jdk的bin目录下面有许多命令,可以很方便的堆虚拟机进行监控或者故障排查等
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
常用命令:
/reset : 清空所有代码
/list: 列出之前写的代码
/history: 列出历史命令
/methods: 列出已声明的方法
/edit: 打开新面板编辑代码:
/drop: 删除,可跟行数或者方法名进行删除
保存与导入:
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 包含这两个注解的信息
例如: 注释一个类:
使用javadoc生成:
也可以直接使用idea生成javadoc,注意要设置编码,其实也是执行的javadoc命令:
注意设置编码直接用 -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字节码进行反编译生成汇编代码。
反汇编后的文件:
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
堆对象直方图,可以很直观的看到每个类产生了多少个实例,以及这些实例共占用了多少内存:
2 jcmd pid GC.class_stats
GC.class_stats相比GC.class_histogram之外,能够提供被加载类的更详细信息,借助它,我们能够看到Metaspace每个类所占据的空间 ,看到每个类的实例所占用多少内存
不过注意: GC.class_stats是一个高开销的诊断命令,它运行在全局SafePoint(STW暂停)中。对VM有很大影响
除其他外,此操作遍历整个堆来计算所有加载类的所有实例占用的内存 ,已被移除在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
演示:
1 先打基线,如果不对比,也可以不打:
2 然后查看内存使用信息:
jcmd VM.native_memory summary scale=MB 可换算单位
3 可以和基线时刻进行对比:
4 输出NMT信息解释:
jconsole
jconsole是JDK内置的图形化Java性能分析工具,可以在命令行运行。启动可以更具Java进程id查看程序的堆使用,线程情况,类信息等。
jhsdb
jhsdbshi JDK 9用于处理性能和可维护性问题的新命令行工具: jhsdb,如果附加到进程,则会导致进程挂起,此命令jdk版本必须和项目保持一致
jhsdb有几种模式,下面简单介绍一下:
所有模式的部分参数:
—pid 挂起进程的进程ID。
—exe 可执行文件名。
—core 核心转储文件名。
—help 显示该命令可用的选项。
jhsdb hsdb模式
启动交互式GUI调试器。可以在GUI界面进行查找信息等操作
还有其他两种debug模式,这里就不说了
jhsdb jstack模式
1 jhsdb jstack —locks —pid 6893 : 检测死锁信息以及打印锁的信息,
我这里程序模拟了一个死锁,检测结果,后续会继续打印所有锁的信息:
jhsdb jmap模式
jhsdb的jmap模式提供的功能跟jmap和jcmd命令提供的功能一样。 这些包括堆转储( —heap ),类直方图( —histo ),类加载器统计( —clstats ),和释放信息( —finalizerinfo )
例如: jhsdb jmap —histo —pid 844
jhsdb jinfo模式
打印基本的JVM信息。此模式和 jinfo以及jcmd命令功能也是一样的,这里不再赘述
jhsdb jsnap模式
jhsdb jsnap —pid 844
打印性能计数器信息。包含启动的线程数,启动参数等等一些信息
jimage
java9提供了新的打包格式jimage,而不再使用jar这种文件格式打包
jar是一个非常老的协议,它是基于很老的zip协议,效率上比较差,空间占用也比较大。
jar是基于文件系统而不是基于module的,也就是说jar打包的原则是把某几个目录下的文件打成一个包
java9模块化之后,就需要一种能通过模块直接加载class的方式,格式针对空间和速度进行了优化,这里简单介绍一下jimage:
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等
“Server is ready.”出现后就可以在浏览器中键入http://localhost:7000 查看分析结果了, 此功能在jdk11之后已被移除
jinfo
主要用于打印配置信息,包括命令行参数、系统变量。极少数的情况下,我们可以用其来修改命令行参数
没有选项直接打印虚拟机参数和系统参数
jinfo -flags 进程号: 打印虚拟机参数
jinfo -sysprops 进程号: 打印系统变量
jinfo -flag +- 进程号:开启或者关闭虚拟机参数
观察运行中的java程序的运行环境参数:参数包括Java System属性和JVM命令行参数、也可以设置参数的值,并使之立即生效。
jmap
jmap可以生成 java 程序的 dump 文件, 也可以查看堆内对象示例的统计信息、查看 ClassLoader 的信息以及 finalizer 队列
-dump: 生成堆转储快照
-histo 显示堆中对象的统计信息:
冷知识:一个最简单的springboot项目初始化会创建26万多个对象(String就有四万多个),总共2780个类
添加live只统计活着的对象
-clstats: 打印类加载器信息
-finalizerinfo 打印等待回收的对象信息
-heap :打印heap堆的概要信息,GC使用的算法,heap的配置及wise heap的使用情况 |
可以生成java应用程序的堆快照和对象统计信息。
下面的命令可以看到java进程中某一时刻的类示例数量以及所占的字节数。
打印进程的类加载器和类加载器加载的持久代对象信息,输出:类加载器名称、对象是否存活(不可靠)、对象地址、父类加载器、已加载的类大小等信息。
1、使用jmap -heap pid查看进程堆内存使用情况,包括使用的GC算法、堆配置参数和各代中堆内存使用情况。
2、使用jmap -histo[:live] pid 查看堆内存中的对象数目、大小统计直方图,如果带上live则只统计活对象
jmc(暂无)
jps
列出正在运行的JVM虚拟机进程并显示主类和进程id等信息
常用的参数:
-l 输出Java应用程序的main class的完整包
-q 仅显示pid,不显示其它任何相关信息
-m 输出传递给main方法的参数
-v 输出传递给JVM的参数。在诊断JVM相关问题的时候,这个参数可以查看JVM相关参数的设置
注:这个命令相信大多数java程序员都知晓、查找当前运行的java进程、当需要kill掉某个进程的时候可以用到。
bogon:~ chengluchao$ jps -l
14064 org.jetbrains.idea.maven.server.RemoteMavenServer
14049
14082 org.jetbrains.jps.cmdline.Launcher
5036 com.baiwang.UserServiceApplication
14095 jdk.jcmd/sun.tools.jps.Jps
jrunscript(暂无)
jsadebugd(暂无)
jstack
java堆栈跟踪工具,用于生成当前时刻虚拟机内每一条线程正在执行的方法堆栈集合,以定位线程出现长时间停顿原因
jstack -l pid:
可以用来查看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
得到进程ID为21711
2.:找出该进程内最耗费CPU的线程 top -Hp pid
TIME列就是各个Java线程耗费的CPU时间,CPU时间最长的是线程ID为21742的线程
printf”%x “21742得到21742的十六进制值为54ee,下面会用到。
3.:jstack上场、它用来输出进程21711的堆栈信息,然后根据线程ID的十六进制值grep,如下:
jstat
jstat可以显示本地或远程虚拟机进程中的类装载、内存、垃圾收集情况、JIT编译等运行数据
格式: jstat 选项 进程ID 间隔时间(毫秒) 查询次数:
其他参数:
jstat [ generalOption | outputOptions vmid [interval[s|ms] [count]] ] ,可以用来查看堆信息,垃圾回收信息等,详细使用命令可以通过man jstat命令来查看。
查看垃圾回收信息
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之后就被移除了,不过可以在官网下载
需要在项目启动的时候添加对应参数:
# 远程服务器ip,对应的端口,是否使用SSL和权限验证等
-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连接,
监控效果如图,还可以查jvm参数信息,线程情况等:
keytool(暂无)
kinit(暂无)
ktab(暂无)
rmid(暂无)
rmiregistry(暂无)
serialver(暂无)
GC日志
打印日志详细信息