文章首发于【Java天堂】,跟随我探索Java进阶之路!
在JDK的bin目录下除了我们熟知的java.exe,javac.exe以外,还提供了很多额外的工具,如下图所示:
可以看到里面有很多额外的工具,了解这些工具对于我们日常排查问题很有帮助,尤其是对于性能问题的定位,熟练掌握这些工具的用法之后,可以借助这些工具来进行相关数据的收集和分析,不至于系统发生性能问题时束手无策。下面我们就挑几个常用的工具来介绍一下
jps:查看虚拟机进程状态
如果你对于Linux操作系统的ps命令有所了解,那么就比较容易理解jps的作用了,jps的作用就是列出正在运行的虚拟机进程。跟linux下运行ps的作用差不多。跃然jps命令比较简单和单一,但它绝对是使用最频繁的JDK命令,没有之一。因为其他工具在运行之前,都需要从jps命令这里拿到虚拟机中运行的进程ID
jsp命令格式:
jps [option] hostid
运行示例:
[root@test-65f8f4f76-md2h4 data]# jps -l
253 sun.tools.jps.Jps
14 /data/goods-ds.jar
命令很简单,一般我们从jps这里拿到虚拟机中进程ID就行了,这里的253
和14
就是ID
jstat:监视虚拟机统计信息
jstat(JVM Statistics Monitoring Tool)是用于监视虚拟机各种运行状态信息的命令行工具。在没有GUI图形界面、只提供了纯文本控制台环境的服务器上,它将是运行期定位虚拟机性能问题的常用工具
jstat命令格式为:
jstat [ option vmid [interval[s|ms] [count]] ]
如果是本地虚拟机, vmid表示虚拟机进程ID,如果是远程主机,那vmid的格式为
[protocol:][//]lvmid[@hostname[:port]/servername]
参数interval和count代表查询间隔和次数,如果省略这2个参数,说明只查询一次
运行示例:
[root@test-65f8f4f76-md2h4 data]# jstat -gcutil 14
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
20.83 0.00 62.94 83.21 94.53 92.43 8956 55.669 16 3.007 58.676
我们使用上面通过jps拿到的虚拟机中进程ID为14的GC运行情况
- S0、S1表示Survivor0、Survivor1的使用比例
- E,表示Eden,新生代Eden区的使用比例
- O,表示Old,老年代的使用比例
- M,Metaspace(或 PermGen,在 Java 8 之前)的使用比例
- CCS,Compressed Class Space 的使用比例
- YGC,表示Young GC的次数
- YGCT,表示Young GC总耗时
- FGC,表示Full GC的次数
- FGCT,表示Full GC总耗时
- GCT,表示GC Time,所有GC总耗时
jstat还有很多命令如下所示:
参数 | 作用 |
---|---|
-class | 监视类加载、卸载数量、总空间以及类装载所耗费的时间 |
-gc | 监视Java堆状况,包括各个区域的容量、已用空间、垃圾收集时间等信息 |
-gccapacity | 监视内容与-gc基本相同,主要关注Java堆各个区域使用到的最大、最小空间 |
-gcutil | 监视内容与-gc基本相同,但输出主要关注已使用空间占总空间的百分比 |
-gccause | 与-gcutil功能一样,但是会额外输出导致上一次垃圾收集产生的原因 |
-gcnew | 监视新生代垃圾收集状况 |
-gcnewcapacity | 监视内容与-gcnew基本相同,输出主要关注使用到的最大、最小空间 |
-gcold | 监视老年代垃圾收集状况 |
-gcoldcapacity | 监视内容与-gcold基本相同,输出主要关注使用到的最大、最小空间 |
-gcpermcapacity | 输出永久代使用到的最大、最小空间 |
-compiler | 输出即时编译器编译过的方法、耗时等信息 |
-printcompilation | 输出已经被即时编译的方法 |
可以根据实际需要,使用不同的命令输出相应的参数
jinfo:查看Java配置信息
jinfo的作用是实时查看虚拟机的各项参数,可以输入参数名称,查看参数的配置值。
jinfo命令格式为:
jinfo [option] pid
运行示例:
[root@test-65f8f4f76-md2h4 data]# jinfo -flag MaxHeapFreeRatio 14
-XX:MaxHeapFreeRatio=80
我们可以通过jinfo -flag
查看虚拟机具体某个参数的值,这个在实际排查问题或者调整虚拟机参数时,是比较有用的。
jmap:查看Java内存映像的工具
jmap命令用于生成堆转储快照,也可以查询Java堆和方法区的详细信息,如空间利用率、当前用的是哪种收集器。
命令格式:
jmap [option] vmid
运行示例:
# jmap生成dump文件
[root@test-65f8f4f76-md2h4 data]# jmap -dump:format=b,file=test.bin 14
Dumping heap to test.bin ...
Heap dump file created
# jmap查看堆中对象统计信息
[root@test-65f8f4f76-md2h4 data]# jmap -histo:live 14 | head -20
num #instances #bytes class name
----------------------------------------------
1: 194514 19182160 [C
2: 193084 4634016 java.lang.String
3: 44948 3955424 java.lang.reflect.Method
4: 119201 3814432 java.util.concurrent.ConcurrentHashMap$Node
5: 51430 3181128 [Ljava.lang.Object;
6: 15712 2952464 [B
7: 19966 2234136 java.lang.Class
8: 52593 2103720 java.util.LinkedHashMap$Entry
9: 19193 1737032 [Ljava.util.HashMap$Node;
10: 9952 1571064 [I
11: 648 1210432 [Ljava.util.concurrent.ConcurrentHashMap$Node;
12: 20388 1141728 java.util.LinkedHashMap
13: 45686 1096464 java.util.ArrayList
14: 30928 989696 java.util.HashMap$Node
15: 46751 748016 java.lang.Object
16: 15172 728256 org.aspectj.weaver.reflect.ShadowMatchImpl
17: 38511 616176 org.apache.ibatis.scripting.xmltags.StaticTextSqlNode
jmap还有一些其他的参数如下所示:
参数 | 作用 |
---|---|
-dump | 生成Java堆转储快照 |
-finalizerinfo | 显示在 F-Queue 中等待Finalizer线程执行 finalize方法的对象。只在Linux/Solaris 平台下有效 |
-heap | 显示Java堆详细信息,如使用哪种回收器、参数配置、分代状况等。只在Linux/Solaris平台下有效 |
-histo | 显示堆中对象统计信息,包括类、实例数量、合计容量 |
-permstat | 以 ClassLoader 为统计口径显示永久代内存状态。只在Linux/Solaris平台下有效 |
-F | 当虚拟机进程对-dump选项没有响应时,可使用这个选项强制生成dump快照。只在Linux/Solaris平台下有效 |
实际在排查性能问题的时候,jmap使用的还是挺多的,-dump可以生成Java堆快照,用于事后分析。
-histo可以查看当前对象的统计信息,这个对于排查大对象很有用。
jhat:分析虚拟机堆转储快照工具
在上面我们介绍了jmap可以使用dump来生成虚拟机的堆转储快照文件,jhat可以与jmap搭配使用来分析生成的堆转储快照文件。
我们就使用上面jmap dump生成出来的test.bin转储文件来实际操作一下
C:\Users\彭章君>jhat test.bin
Reading from test.bin...
Dump file created Mon May 20 10:18:00 CST 2024
Snapshot read, resolving...
Resolving 2153403 objects...
Chasing references, expect 430
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.
可以看jhat使用内置的Web服务器,把分析结果以网页的形式呈现出来,访问http://localhost:7000 就可以看到分析的结果
实际工作中,一般很少会使用jhat来分析dump出来的堆转储文件,因为这个分析过程比较消耗资源和时间,不会直接在服务器上进行,需要另外的机器上去做分析的工作,那既然是另外的机器,就不会受限于服务器的命令行工具,大可使用体验更好的分析工具(VisualVM、Eclipse Memory Analyzer、IBM HeapAnalyzer等),这些工具都有可视化工具,比jhat更好用。
jstack:跟踪Java堆栈
jstack会生成虚拟机当前线程的快照,线程快照就是当前虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的目的通常是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间挂起等,都是导致线程长时间停顿的常见原因。线程出现停顿时通过jstack来查看各个线程的调用堆栈,就可以获知没有响应的线程到底在后台做些什么事情,或者等待着什么资源
jstack命令格式:
jstack [option] vmid
运行示例:
[root@test-65f8f4f76-md2h4 data]# jstack -l 14
......
"pool-90-thread-1" #152 prio=5 os_prio=0 tid=0x00007fda2d6d0800 nid=0x7e runnable [0x00007fd9f18d8000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269)
at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:93)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
- locked <0x000000074952b498> (a sun.nio.ch.Util$3)
- locked <0x000000074952b488> (a java.util.Collections$UnmodifiableSet)
- locked <0x000000074952b440> (a sun.nio.ch.EPollSelectorImpl)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor.execute(AbstractMultiworkerIOReactor.java:343)
at org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager.execute(PoolingNHttpClientConnectionManager.java:221)
at org.apache.http.impl.nio.client.CloseableHttpAsyncClientBase$1.run(CloseableHttpAsyncClientBase.java:64)
at java.lang.Thread.run(Thread.java:750)
Locked ownable synchronizers:
- None
......
以上是输出的其中一个线程运行的状态信息,可以通过当前线程运行的状态来分析可能出现性能问题的线程和运行的代码。
jstack还有一些其他的参数如下所示:
参数 | 作用 |
---|---|
-F | 当正常输出的请求不被响应时,强制输出线程堆栈 |
-l | 除堆栈外,显示关于锁的附加信息 |
-m | 如果调用到本地方法的话,可以显示C/C++的堆栈 |
实际在跟踪的时候,可以根据不同的参数,达到不同的效果。
其他命令和工具
上面列出来的,是实际使用频率较高的工具,主要使用场景是性能问题的定位和调优。除了这些工具,还有一些其他的工具,也在此列出来作为参考。
基础工具
名称 | 主要作用 |
---|---|
jar | 创建和管理JAR文件 |
java | Java 运行工具,用于运行 Class 文件或 JAR 文件 |
javac | 用于Java语言的编译器 |
javadoc | Java的API文档生成器 |
javah | C语言头文件和Stub函数生成器,用于编写JNI方法 |
javap | Java 字节码分析工具 |
jlink | 将Module和它的依赖打包成一个运行时镜像文件 |
jdb | 基于JPDA协议的调试器,以类似于GDB的方式进行调试Java代码 |
jdeps | Java类依赖性分析器 |
jdeprscan | 用于搜索 JAR包中使用了“deprecated”的类,从JDK9开始提供 |
安全工具
名称 | 主要作用 |
---|---|
keytool | 管理密钥库和证书。主要用于获取或缓存Kerberos协议的票据授权票据。允许用户查看本地凭据缓存和密钥表中的条目(用于Kerberos协议) |
jarsigner | 生成并验证JAR签名 |
policytool | 管理策略文件的GUI工具,用于管理用户策略文件(java.policy),在JDK10中被移除 |
国际化工具
名称 | 主要作用 |
---|---|
native2ascii | 本地编码到 ASCI 编码的转换器(Native-t0-ASCI Converter),用于“任意受支持的字符编码”和与之对应的“ASCII编码和Unicode 转义”之间的相互转换 |
远程方法调用工具
名称 | 主要作用 |
---|---|
rmic | Java RMI编译器,为使用JRMP或IOP协议的远程对象生成Stub、skeleton和 Tie 类,也用于生成 OMG IDL |
rmiregistry | 远程对象注册表服务,用于在当前主机的指定端口上创建并启动一个远程对象注册表 |
rimid | 启动激活系统守护进程,允许在虚拟机中注册或激活对象 |
serialver | 生成并返回指定类的序列化版本ID |
性能监控和故障处理工具
名称 | 主要作用 |
---|---|
jps | JVM Process Status Tool,显示指定系统内所有的 HotSpot 虚拟机进程 |
jstat | JVM Statistics Monitoring Tool,用于收集 Hotspot 虚拟机各方面的运行数据 |
jstatd | JVM Statistics Monitoring Tool Daemon,istat的守护程序,启动一个RMI服务器应用程序用于监视测试的 HotSpot虚拟机的创建和终止,并提供一个界面,允许远程监控工具附加到在本地系统上运行的虚拟机。在JDK9中集成到了JHSDB中 |
jinfo | Configuration Info for Java,显示虚拟机配置信息。在JDK9中集成到了JHSDB中 |
jmap | Memory Map for Java,生成虚拟机的内存转储快照(heapdump文件)。在JDK9中集成到了JHSDB中 |
jhat | JVM Heap Analysis Tool,用于分析堆转储快照,它会建立一个HTTP/Web 服务器,让用户可以在浏览器上查看分析结果。在JDK9中被JHSDB代替 |
jstack | Stack Trace for Java,显示虚拟机的线程快照。在JDK9中集成到了JHSDB中 |
jhsdb | Java HotSpot Debugger,一个基于 ServiceabilityAgent的HotSpot进程调试器,从JDK9开始提供 |
isadebugd | Java Serviceability Agent Debug Daemon,适用于Java 的可维护性代理调试守护程序,主要用于附加到指定的Java进程、核心文件,或充当一个调试服务器 |
jcmd | JVM Command,虚拟机诊断命令工具,将诊断命令请求发送到正在运行的Java虚拟机。从JDK7开始提供 |
jconsole | JavaConsole,用于监控Java虚拟机的使用JMX规范的图形工具。它可以监控本地和远程Java虚拟机,还可以监控和管理应用程序 |
jvisualvm | Java VisualVM,一种图形化工具,可在Java虚拟机中运行时提供有关基于Java技术的应用程序(Java应用程序)的详细信息。JavaVsualVM 提供内存和CPU分析、堆转储分析、内存泄漏检测、MBean访问和垃圾收集。从JDK6Update7开始提供;从JDK9开始不再打包入JDK中,但仍保持更新发展,可以独立下载 |
建议收藏本文,可以作为字典使用,有需要的时候可以找到对应的工具。
本文由博客一文多发平台 OpenWrite 发布!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。