一、前言
JDK是软件开发工具包,提供了许多工具用于编译、运行、监控、分析,放置在JDK安装目录下的bin目录中。下图是Linux上JDK8提供工具。
大致介绍
工具名称 | 描述 |
---|---|
appletviewer.exe | 用于运行并浏览applet小程序。 |
apt.exe | 注解处理工具(AnnotationProcessingTool),主要用于注解处理。 |
extcheck.exe | 扩展检测工具,主要用于检测指定jar文件与当前已安装的JavaSDK扩展之间是否存在版本冲突。 |
idlj.exe | IDL转Java编译器(IDL-to-JavaCompiler),用于为指定的IDL文件生成Java绑定。IDL意即接口定义语言(InterfaceDefinitionLanguage)。 |
jabswitch.exe | Java访问桥开关(JavaAccessBridgeswitch),用于启用/禁用Java访问桥。Java访问桥内置于Java7Update6及以上版本,主要为Windows系统平台提供一套访问Java应用的API。 |
jar.exe | jar文件管理工具,主要用于打包压缩、解压jar文件。 |
jarsigner.exe | jar密匙签名工具。 |
java.exe | Java运行工具,用于运行.class字节码文件或.jar文件。 |
javac.exe | Java编译工具(JavaCompiler),用于编译Java源代码文件。 |
javadoc.exe | Java文档工具,主要用于根据Java源代码中的注释信息生成HTML格式的API帮助文档。 |
javafxpackager.exe | JavaFX包装器,用于执行与封装或签名JavaFX应用有关的任务。 |
javah.exe | Java头文件工具,用于根据Java类生成C/C头文件和源文件(主要用于JNI开发领域)。 |
javap.exe | Java反编译工具,主要用于根据Java字节码文件反汇编为Java源代码文件。 |
java-rmi.exe | Java远程方法调用(JavaRemoteMethodInvocation)工具,主要用于在客户机上调用远程服务器上的对象。 |
javaw.exe | Java运行工具,用于运行.class字节码文件或.jar文件,但不会显示控制台输出信息,适用于运行图形化程序。 |
javaws.exe | JavaWebStart,使您可以从Web下载和运行Java应用程序,下载、安装、运行、更新Java应用程序都非常简单方便。 |
jcmd.exe | Java命令行(JavaCommand),用于向正在运行的JVM发送诊断命令请求。 |
jconsole.exe | 图形化用户界面的监测工具,主要用于监测并显示运行于Java平台上的应用程序的性能和资源占用等信息。 |
jdb.exe | Java调试工具(JavaDebugger),主要用于对Java应用进行断点调试。 |
jhat.exe | Java堆分析工具(JavaHeapAnalysisTool),用于分析Java堆内存中的对象信息。 |
jinfo.exe | Java配置信息工具(JavaConfigurationInformation),用于打印指定Java进程、核心文件或远程调试服务器的配置信息。 |
jmap.exe | Java内存映射工具(JavaMemoryMap),主要用于打印指定Java进程、核心文件或远程调试服务器的共享对象内存映射或堆内存细节。 |
jmc.exe | Java任务控制工具(JavaMissionControl),主要用于HotSpotJVM的生产时间监测、分析、诊断。 |
jps.exe | JVM进程状态工具(JVMProcessStatusTool),用于显示目标系统上的HotSpotJVM的Java进程信息。 |
jrunscript.exe | Java命令行脚本外壳工具(commandlinescriptshell),主要用于解释执行javascript、groovy、ruby等脚本语言。 |
jsadebugd.exe | Java可用性代理调试守护进程(JavaServiceabilityAgentDebugDaemon),主要用于附加到指定的Java进程、核心文件,或充当一个调试服务器。 |
jstack.exe | Java堆栈跟踪工具,主要用于打印指定Java进程、核心文件或远程调试服务器的Java线程的堆栈跟踪信息。 |
jstat.exe | JVM统计监测工具(JVMStatisticsMonitoringTool),主要用于监测并显示JVM的性能统计信息。 |
jstatd.exe | jstatd(VMjstatdDaemon)工具是一个RMI服务器应用,用于监测HotSpotJVM的创建和终止,并提供一个接口,允许远程监测工具附加到运行于本地主机的JVM上。 |
jvisualvm.exe | JVM监测、故障排除、分析工具,主要以图形化界面的方式提供运行于指定虚拟机的Java应用程序的详细信息。 |
keytool.exe | 密钥和证书管理工具,主要用于密钥和证书的创建、修改、删除等。 |
kinit.exe | 主要用于获取或缓存Kerberos协议的票据授权票据。 |
klist.exe | 允许用户查看本地凭据缓存和密钥表中的条目(用于Kerberos协议)。 |
ktab.exe | Kerberos密钥表管理工具,允许用户管理存储于本地密钥表中的主要名称和服务密钥。 |
native2ascii.exe | 本地编码到ASCII编码的转换器(Native-to-ASCIIConverter),用于"任意受支持的字符编码"和与之对应的"ASCII编码和(或)Unicode转义"之间的相互转换。 |
orbd.exe | 对象请求代理守护进程(ObjectRequestBrokerDaemon),它使客户端能够透明地定位和调用位于CORBA环境的服务器上的持久对象。 |
pack200.exe | JAR文件打包压缩工具,它可以利用Java类特有的结构,对普通JAR文件进行高效压缩,以便于能够更快地进行网络传输。 |
packager.exe | 这是微软提供的对象包装程序,用于对象安装包。 |
policytool.exe | 策略工具,用于管理用户策略文件(.java.policy)。 |
rmic.exe | JavaRMI编译器,为使用JRMP或IIOP协议的远程对象生成stub、skeleton、和tie类,也用于生成OMGIDL。 |
rmid.exe | JavaRMI激活系统守护进程,rmid启动激活系统守护进程,允许在虚拟机中注册或激活对象。 |
rmiregistry.exe | Java远程对象注册表,用于在当前主机的指定端口上创建并启动一个远程对象注册表。 |
schemagen.exe | XMLschema生成器,用于生成XMLschema文件。 |
serialver.exe | 序列版本命令,用于生成并返回serialVersionUID。 |
servertool.exe | JavaIDL服务器工具,用于注册、取消注册、启动和终止持久化的服务器。 |
tnameserv.exe | JavaIDL瞬时命名服务。 |
unpack200.exe | JAR文件解压工具,将一个由pack200打包的文件解压提取为JAR文件。 |
wsgen.exe | XMLWebService2.0的JavaAPI,生成用于JAX-WSWebService的JAX-WS便携式产物。 |
wsimport.exe | XMLWebService2.0的JavaAPI,主要用于根据服务端发布的wsdl文件生成客户端存根及框架 |
xjc.exe | 主要用于根据XMLschema文件生成对应的Java类。 |
二、关键工具
2.1jps显示所有JAVA进程信息
1.参数信息
若服务的启动命令使用了jar包的相对路径,仅使用jps会查看不到服务全名,只显示jar。加-l可解决该问题。
- -q只输出PID。
- -m输出传递给main方法的参数。对于嵌入式JVM,输出可能为空。
- -l输出应用程序主类的完整包名或应用程序JAR文件的完整路径名。
- -v输出传递给JVM的参数。
- -V通过flags文件(.hotspotrc文件或-XX:Flags=<filename>参数指定的文件)输出传递给JVM的参数。本参数不常用。
- -Joption将选项传递给jps调用的java启动器。例如,-J-Xms48m是将启动内存设置为48兆字节。
2.常用命令
//显示所有Java进程信息jps-lmv//输出【pid,应用名,传给main方法的参数,传给jvm的参数】22693app.jar--spring.profiles.active=prod,sqlfx-Xms2048m
2.2jinfo查看虚拟机配置参数信息
环境变量和JVM参数都可以用jps看。其它的功能使用场景不多。
1.查看虚拟机参数jinfo-flagspid
jinfo-flagspid
输出结果解释:
- Non-default:虚拟机默认设置的参数
- Commandline:用户指定的参数
2.查看虚拟机指定参数jinfo-flag具体参数pid
[root@manager2bin]#jinfo-flagMaxHeapSize7996-XX:MaxHeapSize=2147483648
3.查看环境变量jinfo-syspropspid
jinfo-sysprops7996
4.参数列表
jinfo[options]
2.3jstack
用于生成虚拟机当前时刻的线程快照,包括当前虚拟机内每条线程正在执行的方法堆栈的集合。
1.能排查哪些问题
在如下三种情况生成线程dump
- 本地虚拟机
- 远端虚拟机
- 崩溃产生的core文件
定位线程长时间停顿的原因。通常是
- 线程间死锁
- 死循环、长循环造成的CPU占用过高
- 请求外部资源长时间等待
2.参数信息
命令格式:
- 查看本地虚拟机jstack[option]<pid>
- 查看远端虚拟机jstack[option]server_id@remoteserverIPorhostname
- 查看崩溃产生的core文件jstack[option]executablecore
option代表的参数:
- -F:线程挂起时(hung)使用-l请求不被响应,可以强制输出线程堆栈
- -l:除了堆栈信息外(默认展示synchronized锁的信息),显示锁的附加信息,例如ownablesynchronizers(使用AbstractOwnableSynchronizer实现的锁信息)
- -m:输出java以及C/C的堆栈信息
3.分析实战
这篇文章讲的挺多。jstack工具介绍,举例具体分析过程
大概需要了解的知识点:
- Java线程状态
- Synchromized锁的Monitor及相关状态
- 调用修饰:locked/waitingtolock/waitingon/parkingtowaitfor的含义
2.4jmap
jmap是一个多功能命令,可以查看堆内对象统计信息(每种类实例的大小和数量)、堆的摘要信息(堆配置、GC算法、各区域使用情况)、finalizer队列等
1.参数信息
option:
- nooption:进程的内存映像信息
- heap:堆的摘要,包括GC算法、堆配置信息、各内存使用情况
- histo[:live]:堆中对象的统计信息
- clstats:打印类加载器信息
- finalizerinfo:显示在F-Queue队列等待Finalizer线程执行finalizer方法的对象
- dump::生成堆转储快照
- F:当-dump没有响应时,使用-dump或者-histo参数.在这个模式下,live子参数无效.
2.常用命令
- 命令:jmap-headpid显示堆的摘要信息
[root@manager2bin]#jmap-heap31137AttachingtoprocessID31137,pleasewait...Debuggerattachedsuccessfully.Servercompilerdetected.JVMversionis25.342-b07usingthread-localobjectallocation.ParallelGCwith13thread(s)HeapConfiguration:MinHeapFreeRatio=0MaxHeapFreeRatio=100MaxHeapSize=16848519168(16068.0MB)NewSize=351272960(335.0MB)MaxNewSize=5616173056(5356.0MB)OldSize=703594496(671.0MB)NewRatio=2SurvivorRatio=8MetaspaceSize=21807104(20.796875MB)CompressedClassSpaceSize=1073741824(1024.0MB)MaxMetaspaceSize=17592186044415MBG1HeapRegionSize=0(0.0MB)HeapUsage:PSYoungGenerationEdenSpace:capacity=4565499904(4354.0MB)used=4519485880(4310.117607116699MB)free=46014024(43.88239288330078MB)98.99213613037894%usedFromSpace:capacity=61341696(58.5MB)used=25460768(24.281280517578125MB)free=35880928(34.218719482421875MB)41.50646242321047%usedToSpace:capacity=58195968(55.5MB)used=0(0.0MB)free=58195968(55.5MB)0.0%usedPSOldGenerationcapacity=415760384(396.5MB)used=95344240(90.92735290527344MB)free=320416144(305.57264709472656MB)22.932497580144624%used31043internedStringsoccupying2942680bytes.
[root@manager2bin]#jmap-histo:live31137num#instances#bytesclassname----------------------------------------------1:27806317065360[C2:2769586646992java.lang.String3:1176193763808java.util.HashMap$Node4:824542638528java.util.concurrent.ConcurrentHashMap$Node5:299082392640net.sf.ehcache.Element6:109182127168[B7:238172095896java.lang.reflect.Method8:235272005488[Ljava.util.HashMap$Node;9:108431738832[I10:140791558632java.lang.Class11:225811293976[Ljava.lang.Object;12:299081196320net.sf.ehcache.store.chm.SelectableConcurrentHashMap$HashEntry
[root@APP]#jmap-finalizerinfo6398AttachingtoprocessID6398,pleasewait...Debuggerattachedsuccessfully.Servercompilerdetected.JVMversionis25.342-b07Numberofobjectspendingforfinalization:0
2.5jstat
能够对Java应用程序的资源和性能进行实时的命令行的监控。如GC分析、内存统计等
1.参数信息
查看帮助信息,主要的使用方式为:jstat-<option>PID[间隔时间/毫秒][查询次数]
查看options主要参数:
[root@manager2bin]#jstat-options-class(类加载统计)-compiler(编译统计)-gc(垃圾回收统计)-gccapacity(堆内存统计)-gccause(最近一次GC统计和原因)-gcmetacapacity(JDK8下元数据空间统计)-gcnew(新生代垃圾回收统计)-gcnewcapacity(新生代内存统计)-gcold(老年代垃圾回收统计)-gcoldcapacity(老年代内存统计)-gcutil(总结垃圾回收统计)-printcompilation(JVM编译方法统计)
2.常用命令
- 命令:jstat-gcpid时间间隔(毫秒)次数查看gc信息,单位都是字节
每秒查询1次,共10次。可见新创建的对象都放到Eden区。
[root@manager2bin]#jstat-gc31137100010S0CS1CS0US1UECEUOCOUMCMUCCSCCCSUYGCYGCTFGCFGCTGCT47616.053760.00.00.05367808.01162424.6571904.059226.478800.074311.49728.08823.2120.62840.5111.13847616.053760.00.00.05367808.01162424.6571904.059226.478800.074311.49728.08823.2120.62840.5111.13847616.053760.00.00.05367808.01180319.4571904.059226.478800.074311.49728.08823.2120.62840.5111.13847616.053760.00.00.05367808.01194274.7571904.059226.478800.074311.49728.08823.2120.62840.5111.13847616.053760.00.00.05367808.01220646.5571904.059226.478800.074311.49728.08823.2120.62840.5111.13847616.053760.00.00.05367808.01240688.0571904.059226.478800.074311.49728.08823.2120.62840.5111.13847616.053760.00.00.05367808.01253570.8571904.059226.478800.074311.49728.08823.2120.62840.5111.13847616.053760.00.00.05367808.01260728.0571904.059226.478800.074311.49728.08823.2120.62840.5111.13847616.053760.00.00.05367808.01285790.5571904.059226.478800.074311.49728.08823.2120.62840.5111.13847616.053760.00.00.05367808.01289369.0571904.059226.478800.074311.49728.08823.2120.62840.5111.138
每列含义:
显示列名 | 具体描述 |
---|---|
S0C | 年轻代中第一个survivor(幸存区)的容量(字节) |
S1C | 年轻代中第二个survivor(幸存区)的容量(字节) |
S0U | 年轻代中第一个survivor(幸存区)目前已使用空间(字节) |
S1U | 年轻代中第二个survivor(幸存区)目前已使用空间(字节) |
EC | 年轻代中Eden(伊甸园)的容量(字节) |
EU | 年轻代中Eden(伊甸园)目前已使用空间(字节) |
OC | Old代的容量(字节) |
OU | Old代目前已使用空间(字节) |
MC | 元空间的容量(字节) |
MU | 元空间目前已使用空间(字节) |
CCSC | 压缩类空间大小 |
CCSU | 压缩类空间使用大小 |
YGC | 年轻代垃圾回收次数 |
YGCT | 年轻代垃圾回收消耗时间 |
FGC | 老年代垃圾回收次数 |
FGCT | 老年代垃圾回收消耗时间 |
GCT | 垃圾回收消耗总时间 |
每秒1次,查询15次。可见发生一次youngGC
[root@manager2APP]#jstat-gcutil17180100015S0S1EOMCCSYGCYGCTFGCFGCTGCT0.0038.2430.0069.4194.1891.72574.73941.5016.2400.0038.2436.0069.4194.1891.72574.73941.5016.2400.0038.2444.0069.4194.1891.72574.73941.5016.2400.0038.2455.9969.4194.1891.72574.73941.5016.2400.0038.2461.9969.4194.1891.72574.73941.5016.2400.0038.2465.9969.4194.1891.72574.73941.5016.2400.0038.2475.9969.4194.1891.72574.73941.5016.2400.0038.2487.9969.4194.1891.72574.73941.5016.2400.0038.2497.9969.4194.1891.72574.73941.5016.24046.980.006.0069.4194.1891.72584.75541.5016.25646.980.0016.0069.4194.1891.72584.75541.5016.25646.980.0024.0069.4194.1891.72584.75541.5016.25646.980.0034.0069.4194.1891.72584.75541.5016.25646.980.0042.0069.4194.1891.72584.75541.5016.25646.980.0051.9969.4194.1891.72584.75541.5016.256
各列含义:
显示列名 | 具体描述 |
---|---|
S0 | 幸存1区当前使用比例 |
S1 | 幸存2区当前使用比例 |
E | 伊甸园区使用比例 |
O | 老年代使用比例 |
M | 元数据区使用比例 |
CCS | 压缩使用比例 |
YGC | 年轻代垃圾回收次数 |
FGC | 老年代垃圾回收次数 |
FGCT | 老年代垃圾回收消耗时间 |
GCT | 垃圾回收消耗总时间 |
2.6jconsole
JDK自带的可视化监控工具
1.配置方法
本地进程的监控无需配置,双击想要监控的服务即可。后续只写监控远程进程的配置方法
远程监控jconsoleservice1.服务器JVM配置
找到服务使用Java的lib/management目录,如
#进入对应目录cd/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.102-4.b14.el7.x86_64/jre/lib/management#修改文件名称mvjmxremote.password.templatejmxremote.password#赋权,配置文件可写chmodwjmxremote.password
vim命令打开文件,把controlRole和monitorRole的注释#移除,并保存文件
再次赋权
chmod600/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.102-4.b14.el7.x86_64/jre/lib/management/jmxremote.*
2.启动jar命令修改
java-jar-Djava.rmi.server.hostname=当前服务器IP-Dcom.sun.management.jmxremote.port=指定一个未被占用的端口-Dcom.sun.managent.jmxremote.authenticate=false-Dcom.sun.management.jmxremote.ssl=falsexxx.jar
启动后查看日志正常启动即可。
3.jconsole连接
配置远程连接信息。
- 远程进程处填启动命令配置的【java.rmi.server.hostname】:【com.sun.management.jmxremote.port】
- 用户名和密码填jmxremote.password文件中的monitorRole及后面的密码
可能遇到找不到主机名的问题,参考https://blog.csdn.net/cc920095705/article/details/107891424
连接后结果如图
2.各种参数含义
见深入了解JVM虚拟机第二章
三、常见问题以及解决方法
3.1CPU占用过高
- top-ic发现CPU占比较高
- jstack-l17180>stack.log导出线程堆栈信息
- top-Hp17180查看该进程的线程信息
- printf%x17508将CPU占比高的线程PID转16进制,得到4464
- 在文件中查找4464或者使用命令查看(grep-n-B204464stack.log),可以得知当前线程的状态和正在执行的代码的位置
[root@APP]#grep-n-A504464stack.log507:"pool-1-thread-1"#30prio=5os_prio=0tid=0x00007f50659b7800nid=0x4464runnable[0x00007f4ff22f4000]508-java.lang.Thread.State:RUNNABLE509-atjava.net.SocketOutputStream.socketWrite0(NativeMethod)510-atjava.net.SocketOutputStream.socketWrite(SocketOutputStream.java:111)511-atjava.net.SocketOutputStream.write(SocketOutputStream.java:155)512-atjava.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)513-atjava.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)514--locked<0x00000006cd8c0650>(ajava.io.BufferedOutputStream)...
- -n显示行号
- -A显示当前配置位置之后的多少行
得到位置就可以到代码中定位问题。
3.2无响应/死锁
jstack的线程堆栈信息可以提示死锁。
3.2频繁GC/内存溢出
借助jmap命令、jstat命令可以得知对象创建情况、GC情况,从而定位问题。
服务器命令参考
jmap-histo:live56390>jmap.logjstat-gc56390500020jstat-gcutil56390500020
jar启动参数添加
-XX:HeapDumpOnOutOfMemoryError-XX:HeapDumpPath="./heapdump.hprof"
内存溢出崩溃后会在对应目录下生成heapdump.hprof文件,可以用jvisualVM分析
3.4无任何操作下堆内存占用逐渐升高
现象1:通过jconsole监视堆内存发现占用逐渐升高,此时系统未接受任何请求且代码里无定时任务
推测:内存泄漏
现象2:通过JVisualVM对比两次堆实例,发现多了许多byte[]、ByteBuffer、SocksSocketImpl
推测:存在类似Nacos客户端轮询的请求
导出dump会导致stoptheword
四、总结
常用的
- jps找应用进程PID
- jstack分析死锁(jconsole可以代替)或CPU高的原因(arthas可以代替)
- jmap分析内存泄漏的原因(jvisualVM可以代替)
- jconsole可视化分析内存变化、GC、线程数、死锁比较方便
- jstat常用语分析GC信息(jconsole、arthas都容易代替)
参考
- JDKbin目录下自带的工具介绍,讲解比较详细
- JPS命令
- JPS命令详解、查看其它服务器、失效原因
- Java所有JVM参数VMFlags,罗列了各种参数
- jstack工具介绍,强烈推荐
- stack与Lockedownablesynchronizers
- jvm性能调优工具之jmap
- jconsole的使用