1. 基础故障处理工具
1.1 jps:虚拟机进程状况工具
- jps:JVM Process Status Tool,用于列出正在运行的虚拟机进程,并显示虚拟机执行主类(Main Class,main()函数所在的类)名称以及这些进程的本地虚拟机唯一ID(LVMID,Local Virtual Machine Identifier)。
- jps还可以通过RMI协议查询开启了RMI服务的远程虚拟机进程状态,参数hostid为RMI注册表中注册的主机名。
- jps命令格式:jps [options] [hostid]
- 参数options:
- -q:显示进程ID,省略主类名称;
- -m:显示进程ID,主类名称,虚拟机进程启动时传递给主类main()函数的参数;
- -l:显示进程ID,主类的全类名(如果进程执行的是JAR包,则输出JAR路径);
- -v:显示进程ID,主类名称,虚拟机进程启动时的JVM参数;
- -V:显示进程ID,主类名称(jps = jps -V)。
- 参数hostid:
- 主机或者服务器的IP,如果不指定,默认为当前的主机或者服务器。
- 如果需要查看其他机器上的JVM进程,需要在待查看机器上启动jstatd。
1.2 jstat:虚拟机统计信息监视工具
- jstat:JVM Statistics Monitoring Tool,用于监视虚拟机各种运行状态信息的命令行工具。它可以显示本地或者远程(需要远程主机提供RMI支持,JDK中提供了jstatd工具用于建立远程RMI服务器)虚拟机进程中的类加载、内存、垃圾收集、即时编译等运行时数据。
- jstat命令格式:jstat option vmid [interval [count]]
对于本地虚拟机进程,VMID与LVMID是一致的;
对于远程虚拟机进程,VMID格式为:protocol://lvmid@hostname:port/servername。
参数 interval 和 count 代表查询间隔(默认单位是ms)和次数,如果省略这2个参数,说明只查询1次。
假设需要每250毫秒查询一次进程2764垃圾收集状况,一共查询20次,其命令为:
- jstat -gc 2764 250 20
选项option代表用户希望查询的虚拟机信息,主要分为三类:类加载、垃圾收集、运行期编译状况。
- 参数option:
- -class:监视类加载、卸载数量、总空间以及类装载所耗费的时间;
- -gc:监视Java堆状况,包括Eden区、2个Survivor区、老年代、元空间、压缩类空间等的容量、已用空间以及垃圾收集时间合计等信息;
- -gccapacity:监视内容与 -gc 基本相同,但输出主要关注Java堆各个区域使用到的最大、最小空间;
- -gcutil:监视内容与 -gc 基本相同,但输出主要关注已使用空间占总空间的百分比;
- -gccause:与 -gcutil 功能一样,但是会额外输出导致上一次垃圾收集产生的原因;
- -gcnew:监视新生代垃圾收集状况;
- -gcnewcapacity:监视内容与 -gcnew 基本相同,输出主要关注使用到的最大、最小空间;
- -gcold:监视老年代垃圾收集状况;
- -gcoldcapacity:监视内容与 -gcold 基本相同,输出主要关注使用到的最大、最小空间;
- -gcpermcapacity:输出永久代使用到的最大、最小空间;
- -compiler:输出即时编译器编译过的方法、耗时等信息;
- -printcompilation:输出已经被即时编译的方法。
//监视Java堆状况
D:\workspace_idea\jvm>jps
19424 Launcher
19776 MethodAreaDemo
18900 KotlinCompileDaemon
9960
16796 Jps
D:\workspace_idea\jvm>jstat -gc 19776
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
10752.0 10752.0 0.0 0.0 65024.0 6509.6 173568.0 0.0 4096.0 776.7 0.0 0.0 0 0.000 0 0.000 0.000
CCS → Compressed Class Space → 压缩类空间
- 在 64 位平台上,HotSpot 使用了两个压缩优化技术,Compressed Object Pointers (“CompressedOops”) 和 Compressed Class Pointers。压缩指针,指的是在 64 位的机器上,使用 32 位的指针来访问数据(堆中的对象或 Metaspace 中的元数据)的一种方式。这样有很多的好处,比如 32 位的指针占用更小的内存,可以更好地使用缓存,在有些平台,还可以使用到更多的寄存器。当然,在 64 位的机器中,最终还是需要一个 64 位的地址来访问数据的,所以这个 32 位的值是相对于一个基准地址的值。
- -XX:+UseCompressedOops:允许对象指针压缩。
- -XX:+UseCompressedClassPointers:允许类指针压缩。
- 上面两个参数默认都是开启的,可以手动关闭它们。
- 如果不允许类指针压缩,那么将没有 Compressed Class Space 这个空间,并且 -XX:CompressedClassSpaceSize 这个参数无效。
- -XX:+UseCompressedClassPointers 是需要 -XX:+UseCompressedOops 开启的,所以堆大小如果大于 32G,CompressedOops 自动关闭,CompressedClassPointers 也会关闭的,关闭了就没有 Compressed Class Space 了,这块就是 Class Space 了。
- -XX:CompressedClassSpaceSize 大小的设置也是有限制,因为压缩开关是受制于 32G,所以这个自然也是不能大于 32G,不过 HotSpot 规定了这个参数不准大于 3G,默认值为 1G。
- 如果遇到了
java.lang.OutOfMemoryError: Compressed class space
,就是类太多了,需要结合具体情况去选择 JVM 调优还是 bug 排查。
//查看参数CompressedClassSpaceSize的默认值大小
D:\workspace_idea\jvm>jps
3924 KotlinCompileDaemon
8312 Jps
9960
12524 Launcher
19244 MethodAreaDemo1
D:\workspace_idea\jvm>jinfo -flag CompressedClassSpaceSize 19244
-XX:CompressedClassSpaceSize=1073741824
//1073741824 / 1024 / 1024 / 1024 = 1G 即CompressedClassSpaceSize默认值为1G
1.3 jinfo:Java配置信息工具
- jinfo:Configuration Info for Java,用于实时查看和调整虚拟机各项配置信息。在JDK9中集成到了JHSDB中。
- jinfo命令格式:jinfo [option] pid
- 使用 jps -v 可以查看虚拟机启动时显式指定的参数列表,如果想要查看未被显式指定的参数的系统默认值,可以使用 jinfo -flag 进行查询(如果只限于JDK6或以上版本,也可以使用 java -XX:+PrintFlagsFinal 查看参数默认值)。
- 参数option:
- no option:输出全部的参数和系统属性;
- -flag name:输出对应名称的参数;
- -flag [+|-]name:开启或者关闭对应名称的参数;
- -flag name=value:设定对应名称的参数;
- -flags:输出全部的参数;
- -sysprops:输出系统属性(打印虚拟机进程的 System.getProperties() 的内容)。
- 注意:jinfo虽然可以在Java程序运行时动态地修改虚拟机参数,但并不是所有的参数都支持动态修改。
- 查看被标记为manageable的参数:
java -XX:+PrintFlagsFinal -version | grep manageable
//查看参数NewRatio的大小
D:\workspace_idea\jvm>jps
18900 KotlinCompileDaemon
1016 MethodAreaDemo
17400 Jps
18136 Launcher
9960
D:\workspace_idea\jvm>jinfo -flag NewRatio 1016
-XX:NewRatio=2
1.4 jmap:Java内存映像工具
- jmap:Memory Map for Java,用于生成堆转储快照(一般称为heapdump或dump文件,二进制文件)。它还可以查询finalize执行队列、Java堆和方法区的详细信息,如空间使用率、当前用的是哪种收集器等。在JDK9中集成到了JHSDB中。
- jmap命令格式:jmap [option] vmid
- 参数option:
- no option:查看进程的内存映像信息;
- -dump:生成Java堆转储快照,格式为 jmap -dump:[live,]format=b,file=<filename> vmid,其中live表示只dump出存活的对象;
- -histo:显示堆中对象统计信息,包括类、实例数量、合计容量;
- -heap: 显示Java堆详细信息。
1.5 jhat:虚拟机堆转储快照分析工具
- jhat:JVM Heap Analysis Tool,与jmap搭配使用,用来分析jmap生成的堆转储快照。jhat内置了一个微型的HTTP/Web服务器,生成堆转储快照的分析结果后,可以在浏览器中查看。在JDK9中被JHSDB代替。
1.6 jstack:Java堆栈跟踪工具
- jstack:Stack Trace for Java,用于生成虚拟机当前时刻的线程快照(一般称为threaddump或javacore文件)。线程快照就是当前虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的目的通常是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间挂起等,都是导致线程长时间停顿的常见原因。线程出现停顿时通过jstack来查看各个线程的调用堆栈,就可以获知没有响应的线程到底在后台做些什么事情,或者等待着什么资源。在JDK9中集成到了JHSDB中。
- jstack命令格式:jstack [option] vmid
- 参数option:
- -F:当正常输出的请求不被响应时,强制输出线程堆栈;
- -l:除堆栈外,显示关于锁的附加信息;
- -m:如果调用到本地方法的话,可以显示C/C++的堆栈。
1.7 JDK附带的小工具总结
- 基础工具:
- jar:创建和管理JAR文件;
- java:Java运行工具,用于运行Class文件或JAR文件,格式:java Hello;
- javac:Java前端编译器,格式:javac Hello.java;
- javadoc:Java的API文档生成器;
- javah:C语言头文件和Stub函数生成器,用于编写JNI(Java Native Interface)方法;
- javap:Java字节码分析工具,格式:javap -v -p Hello.class > test.txt;
- jlink:将Module和它的依赖打包成一个运行时镜像文件;
- jdb:基于JPDA协议的调试器,以类似于GDB的方式进行Java代码调试;
- jdeps:Java类依赖性分析器。
- 安全工具:
- keytool:管理密钥库和证书;
- jarsigner:生成并验证JAR签名;
- 远程方法调用工具:
- rmic:Java RMI编译器;
- rmiregistry:远程对象注册表服务,用于在当前主机的指定端口上创建并启动一个远程对象注册表;
- rmid:启动激活系统守护线程,允许在虚拟机中注册或激活对象;
- serialver:生成并返回指定类的序列化版本ID。
- 性能监控与故障处理工具:
- jstatd:JVM Statistics Monitoring Tool Daemon,jstat的守护程序,在JDK9中集成到了JHSDB中;
- jcmd:JVM Command,虚拟机诊断命令工具,将诊断命令请求发送到正在运行的Java虚拟机;
- jhsdb:Java HotSpot Debugger,一个基于服务性代理(SA,Serviceability Agent)的HotSpot进程调试器,始于JDK9;
- jconsole:Java Console,用于监控Java虚拟机的使用JMX规范的图形工具,它可以监控本地和远程Java虚拟机,还可以监控和管理应用程序;
- jvisualvm:Java VisualVM,一种图形化工具,可在Java虚拟机中运行时提供有关基于Java技术的应用程序的详细信息,Java VisualVM提供内存和CPU分析、堆转储分析、内存泄漏检测、MBean访问和垃圾收集;
- jmc:Java Mission Control,包含用于监控和管理Java应用程序的工具,而不会引入与这些工具相关联的性能开销,开发者可以使用jmc命令来创建JMC工具。
2. 可视化故障处理工具
2.1 JHSDB
- JHSDB(Java HotSpot Debugger)是一款基于服务性代理(Serviceability Agent,SA)实现的进程外调式工具。
- 服务性代理是 HotSpot 虚拟机中一组用于映射Java虚拟机运行信息的、主要基于Java语言(含少量JNI代码)实现的API集合。
//启动JHSDB的图形化模式
D:\workspace_idea\jvm>jps
18900 KotlinCompileDaemon
11880 MethodAreaDemo
17400 Jps
18136 Launcher
9960
D:\workspace_idea\jvm>jhsdb hsdb --pid 11880
2.2 JConsole
- JConsole(Java Monitoring and Management Console)是一款基于JMX(Java Management Extensions)的可视化的Java监视与管理控制台工具。它的主要功能是通过JMX的MBean(Managed Bean)对系统进行信息收集和参数动态调整。
- JConsole的启动方式:双击JDK/bin目录下的jconsole.exe启动JConsole,此时弹出的界面中会自动搜索出本机运行的所有虚拟机进程,不需要用户使用jsp工具来查询。
2.3 VisualVM
- VisualVM(All-in-One Java Troubleshooting Tool)即多合一故障处理工具,是功能最强大的运行监视和故障处理程序之一。
- VisualVM的启动方式:双击JDK/bin目录下的jvisualvm.exe启动VisualVM。
2.4 JMC
- JMC(Java Mission Control)是一款可持续在线的监控工具,最初是BEA公司的产品,JMC不仅有可下载的独立程序,更常见的是作为Eclipse的插件来使用。
- JMC的启动方式:双击JDK/bin目录下的jmc.exe启动JMC。
3. HotSpot虚拟机插件及辅助工具
- HotSpot虚拟机的插件和辅助工具存放在HotSpot源码的 hotspot/src/share/tools 目录下,包括:Ideal Graph Visualizer、Client Compiler Visualizer、MakeDeps、Project Creator、LogCompilation、HSDIS。