Tomcat__05_JVM_排障工具


JVM 运维实用排障工具

1、jps

用来查看Java进程的具体状态, 包括进程ID,进程启动的路径及启动参数等等,与unix上的ps类似,只不过jps是用来显示java进程,可以把jps理解为ps的一个子集。
常用参数如下:
-q:忽略输出的类名、Jar名以及传递给main方法的参数,只输出pid
-m:输出传递给main方法的参数,如果是内嵌的JVM则输出为null
-l:输出完全的包名,应用主类名,jar的完全路径名
-v:输出传给jvm的参数

注意: 使用jps 时的运行账户要和JVM 虚拟机启动的账户一致。若启动JVM虚拟机是运行的账户为www,那使用jps指令时,也要使用www 用户去指定。 sudo -u www jps

Example

// 查看已经运行的JVM 进程的实际启动参数
[root@mouse03 bin]# jps  -v
38372 Jps -Dapplication.home=/usr/local/jdk -Xms8m
38360 Bootstrap -Djava.util.logging.config.file=/data0/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Xms4096m -Xmx4096m -XX:PermSize=1024m -XX:MaxPermSize=2048m -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dignore.endorsed.dirs= -Dcatalina.base=/data0/tomcat -Dcatalina.home=/data0/tomcat -Djava.io.tmpdir=/data0/tomcat/temp

2、jstack

jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息。如果现在运行的java程序呈现hung的状态,jstack是非常有用的。此信息通常在运维的过程中被保存起来(保存故障现场),以供RD们去分析故障。
常用参数如下:
jstack <pid>
jstack [-l] <pid> //长列表. 打印关于锁的附加信息
jstack [-F] <pid> //当’jstack [-l] pid’没有响应的时候强制打印栈信息

Example

// 打印JVM 的堆栈信息,以供问题排查
[root@mouse03 ~]# jstack -F 38360 > /tmp/jstack.log

3、jinfo

可以查看或修改运行时的JVM进程的参数。
常用参数:
jinfo [option] pid

where <option> is one of:
    -flag <name>         to print the value of the named VM flag
    -flag [+|-]<name>    to enable or disable the named VM flag
    -flag <name>=<value> to set the named VM flag to the given value
    -flags               to print VM flags

Example

// 根据 PID 查看目前分配的最大堆栈
[root@mouse03 ~]# jinfo -flag MaxHeapSize 38360
-XX:MaxHeapSize=4294967296
// 动态更改 JVM 的最大堆栈值
[root@mouse03 ~]# jinfo -flag MaxHeapSize=4294967296  38360
Exception in thread "main" com.sun.tools.attach.AttachOperationFailedException: flag 'MaxHeapSize' cannot be changed

    at sun.tools.attach.LinuxVirtualMachine.execute(LinuxVirtualMachine.java:229)
    at sun.tools.attach.HotSpotVirtualMachine.executeCommand(HotSpotVirtualMachine.java:261)
    at sun.tools.attach.HotSpotVirtualMachine.setFlag(HotSpotVirtualMachine.java:234)
    at sun.tools.jinfo.JInfo.flag(JInfo.java:134)
    at sun.tools.jinfo.JInfo.main(JInfo.java:81)

// jinfo 并不能动态的改变所有的JVM 参数。 那到底有哪些参数能够被动态的改变呢?
// java -XX:+PrintFlagsFinal -version 答应JVM 的所有参数
// java -XX:+PrintFlagsFinal -version | grep manageable

[root@mouse03 ~]# java -XX:+PrintFlagsFinal -version | grep manageable
     intx CMSAbortablePrecleanWaitMillis            = 100                                 {manageable}
     intx CMSTriggerInterval                        = -1                                  {manageable}
     intx CMSWaitDuration                           = 2000                                {manageable}
     bool HeapDumpAfterFullGC                       = false                               {manageable}
     bool HeapDumpBeforeFullGC                      = false                               {manageable}
     bool HeapDumpOnOutOfMemoryError                = false                               {manageable}
    ccstr HeapDumpPath                              =                                     {manageable}
    uintx MaxHeapFreeRatio                          = 70                                  {manageable}
    uintx MinHeapFreeRatio                          = 40                                  {manageable}
     bool PrintClassHistogram                       = false                               {manageable}
     bool PrintClassHistogramAfterFullGC            = false                               {manageable}
     bool PrintClassHistogramBeforeFullGC           = false                               {manageable}
     bool PrintConcurrentLocks                      = false                               {manageable}
     bool PrintGC                                   = false                               {manageable}
     bool PrintGCDateStamps                         = false                               {manageable}
     bool PrintGCDetails                            = false                               {manageable}
     bool PrintGCID                                 = false                               {manageable}
     bool PrintGCTimeStamps                         = false                               {manageable}

// 也只有以上这些值才能够动态的被改变
[root@mouse03 ~]# jinfo -flag CMSWaitDuration=1900  38360
# 查看, jinfo -flags 查看 JVM 的 flags 
[root@mouse03 ~]# jinfo -flags 38360
Attaching to process ID 38360, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.91-b14
Non-default VM flags: -XX:CICompilerCount=2 -XX:CMSWaitDuration=1900 -XX:InitialHeapSize=4294967296 -XX:MaxHeapSize=4294967296 -XX:MaxNewSize=1431633920 -XX:MinHeapDeltaBytes=196608 -XX:NewSize=1431633920 -XX:OldSize=2863333376 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps
Command line:  -Djava.util.logging.config.file=/data0/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Xms4096m -Xmx4096m -XX:PermSize=1024m -XX:MaxPermSize=2048m -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dignore.endorsed.dirs= -Dcatalina.base=/data0/tomcat -Dcatalina.home=/data0/tomcat -Djava.io.tmpdir=/data0/tomcat/temp

4、jstat

// 监控JVM 的状态,常用指令:
# jstat -gc 113059 1000 10 // 打印PID 为 113059 JVM 状态,一共打印10次,每次间隔时间为1s(1000ms)
// 注 jstat 的用法超级强大, 我们这里只是列举出列其中一个简单的应用。

Example

# jstat -gc 113059 1000 10
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       PC     PU    YGC     YGCT    FGC    FGCT     GCT
195904.0 195904.0  0.0   21610.3 1567680.0 1516721.9 8526272.0  3557507.8  1048576.0 163148.4   2577   92.033   0      0.000   92.033
195904.0 195904.0 23600.9  0.0   1567680.0 142541.6 8526272.0  3558435.8  1048576.0 163148.4   2578   92.060   0      0.000   92.060
195904.0 195904.0 23600.9  0.0   1567680.0 266338.1 8526272.0  3558435.8  1048576.0 163148.4   2578   92.060   0      0.000   92.060
195904.0 195904.0 23600.9  0.0   1567680.0 413941.8 8526272.0  3558435.8  1048576.0 163148.4   2578   92.060   0      0.000   92.060
195904.0 195904.0 23600.9  0.0   1567680.0 642390.6 8526272.0  3558435.8  1048576.0 163148.4   2578   92.060   0      0.000   92.060
195904.0 195904.0 23600.9  0.0   1567680.0 813957.3 8526272.0  3558435.8  1048576.0 163148.4   2578   92.060   0      0.000   92.060
195904.0 195904.0 23600.9  0.0   1567680.0 984223.2 8526272.0  3558435.8  1048576.0 163148.4   2578   92.060   0      0.000   92.060
195904.0 195904.0 23600.9  0.0   1567680.0 1155472.7 8526272.0  3558435.8  1048576.0 163148.4   2578   92.060   0      0.000   92.060
195904.0 195904.0 23600.9  0.0   1567680.0 1399228.5 8526272.0  3558435.8  1048576.0 163148.4   2578   92.060   0      0.000   92.060
195904.0 195904.0  0.0   23866.6 1567680.0 38005.6  8526272.0  3559196.7  1048576.0 163148.4   2579   92.092   0      0.000   92.092

字段意义如下

列名 说明
S0C 新生代中Survivor space中S0当前容量的大小(KB)
S1C 新生代中Survivor space中S1当前容量的大小(KB)
S0U 新生代中Survivor space中S0容量使用的大小(KB)
S1U 新生代中Survivor space中S1容量使用的大小(KB)
EC Eden space当前容量的大小(KB)
EU Eden space容量使用的大小(KB)
OC Old space当前容量的大小(KB)
OU Old space使用容量的大小(KB)
PC Permanent space当前容量的大小(KB)
PU Permanent space使用容量的大小(KB)
YGC 从应用程序启动到采样时发生 Young GC 的次数
YGCT 从应用程序启动到采样时 Young GC 所用的时间(秒)
FGC 从应用程序启动到采样时发生 Full GC 的次数
FGCT 从应用程序启动到采样时 Full GC 所用的时间(秒)
GCT T从应用程序启动到采样时用于垃圾回收的总时间(单位秒),它的值等于YGC+FGC

5、jvmtop

以上介绍的jps、jstack、jinfo等都是安装JDK 时自带的系统分析工具,而jvmtop是一款开源的JVM工具。
它的下载地址如下: https://github.com/patric-r/jvmtop
顾名思义,它是一个只针对JVM的工具,展示的方式和unix的top命令相似.
jvmtop 提供了两个视图,一个是概览视图,可以展示出当前机器的所有的 JVM 的情况. 还有一个视图是详情视图,展示一个 JVM 的详细情况.

概览视图

jvmtop.sh

YHC9BV.png

其中,各个字段的意义分别如下:
PID:进程 ID
MAIN-CLASS:main 类的名字
HPCUR:当前被使用的 heap 的大小
HPMAX:最大可用的 heap 的大小
NHCUR:当前被使用的非 heap 大小(比如:perm gen)
NHMAX:最大可用的非 heap 大小
CPU:CPU 的使用情况
GC:消耗在 GC 上的时间比例
VM:JVM 的提供者,大版本号,小版本号,图中的意思是 Apple 提供的 JDK 6U51 版本。
USERNAME:当前的用户名
#T:线程数量
DL:是否有现成发生死锁

详情视图

jvmtop.sh <pid>

YHCiAU.png

其中,各个字段的意义如下:
TID:线程 ID
NAME:线程名
STATE:线程状态
CPU:线程当前的 CPU 占用情况
TOTALCPU:从线程被创建开始总体的 CPU 占用情况
BLOCKBY:阻塞这个线程的线程 ID

 上一篇
网络解析与抓包工具 网络解析与抓包工具
网络解析与抓包–简介本文简述一下内容: TCP三次握手和四次挥手 网络分析工具tcpdump抓包 No.1 tcp三次握手和四次挥手—确认ACK, 仅当ACK=1时, 确认号字段才有效. TCP规定在连接建立后所有报文的传输都必须把AC
2020-05-21
下一篇 
Kubernetes-Namespace-配置默认的内存请求和限制 Kubernetes-Namespace-配置默认的内存请求和限制
为命名空间配置默认的内存请求和限制 本文介绍怎样给命名空间配置默认的内存请求和限制。 如果在一个有默认内存限制的命名空间创建容器,该容器没有声明自己的内存限制时, 将会被指定默认内存限制。 Kubernetes 还为某些情况指定了默认的内存
2020-04-01
  目录