一、概述
给系统定位问题的时候,知识经验是关键,数据是依据,工具是运用知识处理问题的手段。这里说的数据包括:运行日志、异常堆栈、GC日志、线程快照(threaddump/javacore文件)、堆转储快照(heapdump/hprof文件)等。
二、jdk的命令行工具
jps:虚拟机进程状况工具
jps(JVM Process Status)可以列出正在运行的虚拟机进程并显示虚拟机执行主类和本地虚拟机唯一ID,对于本地虚拟机,
虚拟机id和与进程id是一致的。jps的命令格式为
jps [ options ] [ hostid ]
样例:前面是进程id 后面是主类
pengweiwei@weiweideMacBook-Pro bin % jps -l
40690
47513 org.apache.catalina.startup.Bootstrap
47518 sun.tools.jps.Jps
jstat:虚拟机统计信息监视工具
jstat(JVM Statistics Monitoring Tool)是用于监视虚拟机各种运行状态和信息的命令行工具。它可以显示本地和远程的虚拟机
进程中的类装载、内存、垃圾收集、JIT编译等运行数据,它是运行期定位虚拟机性能问题的首选工具。
jstat的格式为:jstat [ option vmid [interval [s | ms] [count] ] ] ,
本地虚拟机进程,vmid 和 lvmid是一致的,如果是远程的,则不一样。
option可选项有 gc、class、compiler......(具体可查看深入理解java虚拟机105页),后面两个参数是表示每多少毫秒查询一次,
一共多少次,不选则默认一次。
样例:
pengweiwei@weiweideMacBook-Pro bin % jstat -gc 47513
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
21504.0 21504.0 0.0 0.0 131584.0 123801.3 349696.0 0.0 4480.0 774.6 384.0 75.9 0 0.000 0 0.000 0.000
S0C:第一个Survivor区的大小 (KB)
S1C:第二个Survivor区的大小(KB)
S0U:第一个Survivor区 的使用大小(KB)
S1U:第二个Survivor区 的使用大小(KB)
EC: Eden区的大小(KB)
EU: Eden区 的使用大小(KB)
OC: Old区大小(KB)
OU: Old使 用大小(KB)
MC:方法区大小(KB)
MU:方法区使用大小(KB)
CCSC:压缩类空间大小(KB)
CCSU:压缩类空间使用大小(KB)
YGC:年轻代垃圾回收次数
YGCT:年轻代垃圾回收消耗时间
pengweiwei@weiweideMacBook-Pro bin % jstat -compiler 47513
Compiled Failed Invalid Time FailedType FailedMethod
2011 0 0 2.30 0
Compiled:编译数量
Failed:失败数量
Invalid:不可用数量
Time:时间
FailedType:失败类型
FailedMethod:失败的方法
jinfo:java配置信息工具
jinfo(Configuration Info for java)的作用是实时的查看和调整虚拟机各项参数。使用jps -v 可以查看虚拟机启动时显示指定的
参数列表。但如果想知道未被显示指定的参数的系统默认值,可以使用jinfo -flag进行查询
样例:jinfo pid
pengweiwei@weiweideMacBook-Pro bin % jinfo 47513
Attaching to process ID 47513, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.151-b12
Java System Properties:
java.vendor = Oracle Corporation
sun.java.launcher = SUN_STANDARD
catalina.base = /Users/pengweiwei/Downloads/apache-tomcat-8.5.50
sun.management.compiler = HotSpot 64-Bit Tiered Compilers
catalina.useNaming = true
os.name = Mac OS X
sun.boot.class.path = /Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/sunrsasign.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/classes
jinfo -flag
pengweiwei@weiweideMacBook-Pro bin % jinfo -flag CMSInitiatingOccupancyFraction 47513
-XX:CMSInitiatingOccupancyFraction=-1
jmap:java内存映像工具(配合jhat)
jmap(Memory Map for java)是用于生成堆转储快照的,还可以查询finalize执行队列、java堆和永久代的详细信息,如空间使用率、
当前使用的是哪种收集器等。
格式为:jmap [ option ] vmid
pengweiwei@weiweideMacBook-Pro Downloads % jmap -dump:format=b,file=tomcat.dump 47513
Dumping heap to /Users/pengweiwei/Downloads/tomcat.dump ...
Heap dump file created
jhat:虚拟机堆转储快照分析工具
jhat(JVM Heap Analysic Tool)是用来分析jmap生成的dump文件,它内置了一个HTTP/HTML服务器,分析完成后可以在浏览器中查看,
不过功能比较简陋,不常用。
用法:
pengweiwei@weiweideMacBook-Pro Downloads % jhat tomcat.dump
Reading from tomcat.dump...
Dump file created Sat Dec 21 20:06:55 CST 2019
Snapshot read, resolving...
Resolving 260024 objects...
Chasing references, expect 52 dots....................................................
Eliminating duplicate references....................................................
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.
然后访问 http://localhost:7000/ 即可查看结果。
jstack:java堆栈跟踪工具
jstack(Stack Trace for Java)用于生成虚拟机当前时刻的线程快照。线程快照就是当前虚拟机内每条线程正在执行的方法堆栈的集合,
生成线程快照的主要目的就是为了定位线程出现长时间等待的原因,比如线程间的死锁、死循环、请求外部资源导致的长时间等待等。
用法:jstack [ option ] vmid
option的主要选项有:
- -F : 当正常输出的请求不被响应时,强制输出线程堆栈
- -l : 除了堆栈信息外,显示关于锁的信息。
- -m:如果调用到本地方法的话,可以显示C/C++的堆栈
示例:
pengweiwei@weiweideMacBook-Pro Downloads % jstack -l 47513
2019-12-22 17:58:04
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.151-b12 mixed mode):
"Attach Listener" #56 daemon prio=9 os_prio=31 tid=0x00007ffd690da800 nid=0x9c07 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"ajp-nio-8009-AsyncTimeout" #54 daemon prio=5 os_prio=31 tid=0x00007ffd79140800 nid=0xb203 waiting on condition [0x000070000d490000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at org.apache.coyote.AbstractProtocol$AsyncTimeout.run(AbstractProtocol.java:1162)
at java.lang.Thread.run(Thread.java:748)
Locked ownable synchronizers:
- None
"ajp-nio-8009-Acceptor-0" #53 daemon prio=5 os_prio=31 tid=0x00007ffd79140000 nid=0xb003 runnable [0x000070000d38d000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.ServerSocketChannelImpl.accept0(Native Method)
at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:422)
at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:250)
- locked <0x000000071d618230> (a java.lang.Object)
at org.apache.tomcat.util.net.NioEndpoint$Acceptor.run(NioEndpoint.java:484)
at java.lang.Thread.run(Thread.java:748)
Locked ownable synchronizers:
- None
从给出的信息能看出线程的状态,又没有出现死锁,死锁的位置在哪里等。
三、jdk的可视化工具
jdk除了提供了大量的命令之外,还提供了两个功能强大的可视化工具,Jconsole 和 VisualVM
Jconsole:java监视和管理控制台
1. 启动Jconsole
连接上我们启动的tomcat
可以看到有内存、线程、类、VM概要、MBean几个标签
2.内存监控
内存页签相当于jstat命令,用于监视收集器管理的虚拟机内存(java堆和永久代)的变化趋势。
3.线程监控
线程监控相当于jstack命令,当线程执行很慢(某个接口响应时间很慢)的时候,就可以来这里来进行监控分析。
VisualVM:多合一故障处理工具
VisulaVM是目前随JDK发布的功能最强大的行动监视和故障处理工具。
它可以做到:
- 显示虚拟机进程以及进程的配置、环境信息(jps、jinfo)。
- 监视应用程序的CPU、GC、堆、方法区以及线程的信息(jstat、jstack)。
- dump以及dump文件分析(jmap、jhat)。
- 方法级的程序运行性能分析,找出被调用最多、运行时间最长的方法。
- 离线程序快照:收集程序的运行时配置、线程dump、内存dump等信息建立一个快照,可以将快照发送给开发者进行BUG反馈。
- 其他插件的功能…
打开后是这样子的
当然,光监视本地的是作用不大的,可以利用JMX(jaav Management Extensions)监控远程服务器的状态。
具体步骤:
#在tomcat的bin目录下,修改catalina.sh,添加如下的参数
JAVA_OPTS="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=6666 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl-false"
#这几个参数的意思是:
#-Dcom.sun.management.jmxremote:允许使用JMX远程管理
#-Dcom.sun.management.jmxremote.port=6666:JMX远程连接端口
#-Dcom.sun.management.jmxremote.authenticate=false:不进行身份认证,任何用户都可以连接
#-Dcom.sun.management.jmxremote.ssl-false:不使用ssl
然后重启tomcat
等待连接成功就行。