一、监控工具:
1.jps:
(1)格式:
jps -命令 IP或域名 #默认使用rmi格式,rmi协议默认端口1099
jps -命令 协议名://IP或域名:端口
(2)命令列表(可以多个参数联用):
q:查看进程ID
m:查看传给main的参数
l:查看应用main class类全名
v:查看传给jvm的参数
V:隐藏传给jvm的参数
(3)使用:
jps -q rmi://192.168.233.130:8080
2.jstat:
(1)格式([]表示可选,-t为采样耗时,采样次数不写默认为1):
jstat -命令 [-t] [-h行数] 进程ID[@IP或域名:端口] 采样间隔毫秒 [采样次数]
(2)命令列表:
<1>class,显示类加载器统计信息,输出如下:
Loaded:当前加载类的数量
Bytes:当前加载的空间,单位KB
Unloaded:卸载类的数量
Bytes:当前卸载的空间,单位KB
Time:类加载/卸载耗时
<2>compiler,显示即时编译器行为统计信息,输出如下:
Compiled:编译次数
Failed:编译失败次数
Invalid:无效的编译次数
Time:编译耗时
FailedType:上次编译失败的类型
FailedMethod:上次编译失败的类/方法名
<3>gc,查看垃圾收集堆行为统计信息,输出如下:
S0C:第1个存活区总容量,单位KB
S1C:第2个存活区总容量,单位KB
S0U:第1个存活区已用容量,单位KB
S1U:第2个存活区已用容量,单位KB
EC:Eden空间总容量,单位KB
EU:Eden空间已用容量,单位KB
OC:老年代总容量,单位KB
OU:老年代已用容量,单位KB
MC:元空间总容量,单位KB
MU:元空间已用容量,单位KB
CCSC:压缩的类空间总容量,单位KB
CCSU:压缩的类空间已用容量,单位KB
YGC:年轻代垃圾回收事件数量
YGCT:年轻代垃圾回收时间
FGC:Full GC事件数量
FGCT:Full GC回收时间
GCT:垃圾回收总耗时
<4>gccapacity,查看新生代、老年代、持久代容量信息,输出如下:
NGCMN:最小年轻代容量,单位KB
NGCMX:最大年轻代容量,单位KB
NGC:当前年轻代容量,单位KB
S0CMX:最大S0容量,单位KB
S0C:当前S0容量,单位KB
S1CMX:最大S1容量,单位KB
S1C:当前S1容量,单位KB
ECMX:最大Eden空间容量,单位KB
EC:当前Eden空间容量,单位KB
YGC:年轻代GC事件数量
FGC:Full GC事件数量
<5>gccause,查看触发垃圾回收的原因,输出如下:
LGCC:GC原因
GCC:当前GC原因
<6>gcnew,查看新生代行为统计信息,输出如下:
S0C:第1个存活区容量,单位KB
S0U:第1个存活区利用率,单位KB
S1C:第2个存活区容量,单位KB
S1U:第2个存活区利用率,单位KB
T1:老年代阀值
MTT:最大老年代阀值
DSS:期望存活区容量,单位KB
EC:当前Eden空间容量,单位KB
EU:Eden空间利用率,单位KB
YGC:年轻代GC发生次数
YGCT:年轻代码垃圾回收耗时
<7>gcnewcapacity,查看新生代容量,输出如下:
NGCMN:最小年轻代容量,单位KB
NGCMX:最大年轻代容量,单位KB
NGC:当前年轻代容量,单位KB
S0CMX:最大S0容量,单位KB
S0C:当前S0容量,单位KB
S1CMX:最大S1容量,单位KB
S1C:当前S1容量,单位KB
ECMX:最大Eden空间容量,单位KB
EC:当前Eden空间容量,单位KB
YGC:年轻代GC发生次数
FGC:Full GC发生次数
<8>gcold,查看老年代、元空间统计信息,输出如下:
MC:当前元空间已用容量,单位KB
MU:元空间利用率,单位KB
CCSC:压缩类大小,单位KB
CCSU:使用压缩类空间,单位KB
OC:当前老年代容量,单位KB
OU:年轻代利用率,单位KB
YGC:年轻代GC发生次数
FGC:Full GC发生次数
FGCT:Full GC回收耗时
GCT:总垃圾回收耗时
<9>gcoldcapacity,查看老年代容量,输出如下:
OGCMN:最小老年代容量,单位KB
OGCMX:最大老年代容量,单位KB
OGC:当前老年代容量,单位KB
OC:当前old space容量,单位KB
YGC:年轻代GC发生次数
FGC:Full GC发生次数
FGCT:Full GC回收耗时
GCT:总回收耗时
<10>gcmetacapacity,查看元空间容量,输出如下:
MCMN:最小元空间容量,单位KB
MCMX:最大元空间容量,单位KB
MC:元空间容量,单位KB
CCSMN:压缩的类空间最小容量,单位KB
CCSMX:压缩的类空间最大容量,单位KB
YGC:年轻代GC发生次数
FGC:Full GC发生次数
FGCT:Full GC回收耗时
GCT:总回收耗时
<11>gcutil,查看垃圾回收信息摘要,输出如下:
S0:第1个存活区利用率
S1:第2个存活区利用率
E:Eden空间利用率
O:老年代空间利用率
M:元空间利用率
CCS:压缩的类空间利用率
YGC:年轻代GC发生次数
YGCT:年轻代回收耗时
FGC:Full GC发生次数
FGCT:Full GC回收耗时
GCT:总回收耗时
<12>printcompilation,查看Java HotSpot VM编译方法统计信息,输出如下:
Compiled:最近方法的编译任务数
Size:方法的字节数
Type:方法的编译类型
Method:标识方法的类名/方法,格式与-XX:+PrintCompilation选项一致
(3)使用:
jstat -gcutil 进程ID 采样间隔毫秒 采样次数 #查看该进程垃圾回收信息摘要
jstat -gccapacity -h3 进程ID 采样间隔毫秒 采样次数 #查看新生代、老年代、持久代容量信息
jstat -gcutil 进程ID@域名:端口 采样间隔毫秒 采样次数 #查看指定服务器进程垃圾回收信息摘要
二、故障排查工具:
1.jinfo:
(1)格式:
jinfo -命令 进程ID
(2)命令列表:
flags:查看VM参数
flag 参数名:查看某参数的值
flag +参数名:启用某参数
flag -参数名:停用某参数
flag 参数名=值:将值赋值给某参数
sysprops:查看系统属性
(3)使用:
jinfo 进程ID #查看此进程VM参数与系统属性
jinfo -flags 进程ID #查看此进程VM参数
jinfo -flag 参数名 进程ID #查看此进程某参数的值
jinfo -flag 参数名=值 进程ID #将值赋值给此进程某参数
jinfo -sysprops 进程ID #查看此进程系统属性
java -XX:+PrintFlagsInitial | grep manageable #查看参数名列表
2.jmap:
(1)格式:
jmap -命令 进程ID
jmap -命令 服务器IP或域名
(2)命令列表:
-heap:查看Java堆摘要
-histo[:live]:查看堆直方图,:live选项只看活动对象
-clstats:查看类加载器的统计信息
-finalizerinfo:查看等待结束的对象的信息
-dump:值 :dump堆中的对象,值为live(dump活动对象)、format=b(以二进制格式dump)、file=文件名.hprof(dump到文件)
(3)使用:
jmap -heap 进程ID #查看此进程堆摘要
jmap -finalizerinfo 进程ID #查看此进程等待结束的对象的信息
jmap -clstats 进程ID #查看此进程类加载器的统计信息
jmap -histo:live 进程ID #查看此进程堆中活动对象直方图
jmap -dump:live,format=b,file=文件名.hprof 进程ID #dump堆活动对象到文件名.hprof
3.jstack:
(1)格式:
jstack -命令 进程ID
jstack -命令 服务器IP或域名
(2)命令列表(可多个一起使用):
F:强制线程转储。当jstack 没有响应(进程挂起)时使用
l:查看锁的附加信息
m:查看Java和本机帧(混合模式)
e:查看线程额外信息(分配内存、类等信息)
(3)使用:
jstack -l 进程ID #查看此进程锁的附加信息
4.jcmd:
(1)格式:
jcmd 进程ID或启动类全名 PerfCounter.print #查看此进程或此应用可用的性能计数器
jcmd 进程ID或启动类全名 -f 文件名 #从文件中读取命令执行
jcmd -l #列出本地机器上的JVM进程
jcmd -h #查看帮助
jcmd 进程ID或启动类全名 命令 #查看可用命令列表:jcmd 进程名 help
(2)命令列表:
Compiler.codecache:输出代码缓存布局和边界
Compiler.codelist:查看代码缓存运行中的方法
Compiler.queue:
Compiler.directives_add 指令文件名称 指令:从文件添加编译器指令
Compiler.directives_clear:删除所有编译器指令
Compiler.directives_print:查看活动的编译器指令
Compiler.directives_remove:删除最新添加的编译器指令
GC.class_histogram [-all]:查看堆使用情况的统计信息
GC.class_stats [-all | -csv | -help] [InstBytes,KlassBytes,CpAll,annotations,MethodCount,Bytecode,MethodAll,ROAll,RWAll,Toal > 文件名.csv]:查看类元数据的统计信息,-csv为生成csv文件,最后一参数为要显示的列,显示多个列以逗号隔开
CG.finalizer_info:查看finalization queue信息
CG.heap_dump [-all] [文件名.hprof]:Dump堆为hprof文件
CG.heap_info:查看堆信息
CG.run:执行System.runFinalization()
JVMTI.agent_load [library jvmit路径 | agent option]:加载jvmti本机代理
JVMTI.data_dump:对jvmti进行数据转储
ManagementAgent.start [options]:启动远程管理代理
ManagementAgent.start_local:启动本地管理代理
ManagementAgent.stop:停止远程管理代理
Thread.print [-l]:查看带堆栈跟踪的线程
VM.unlock_commercial_features:解锁商业功能
VM.classloader_stats:查看所有类加载器的统计信息
VM.class_hierarchy [-i | -s] [类全名]:查看已加载类的列表,类名称后附带类加载器信息
VM.command_line:查看启于此VM实例的命令行
VM.dynlibs:查看加载的动态库
VM.info:查看JVM环境与状态信息
VM.log [output | output_options | what | decorators | disable list | rotate]:查看日志配置/启用/禁用/配置日志输出
VM.flags [-all]:查看VM标志及其当前值
VM.native_memory [summary | detail | baseline | summary.diff | detail.diff | shutdown | statistics | scale]:查看native内存使用情况(打开:-XX:NativeMemoryTracking=[off | summary | detail])
VM.print_touched_methods:查看JVM接触过的生命周期方法
VM.set_flag [标志名称 | 字符串值]:设置VM标志
VM.stringtable [-verbose]:转储字符串表
VM.symboltable [-verbose]:转储符号表
VM.systemdictionary [-verbose]:查看字典哈希表大小和存储桶长度的统计信息
VM.system_properties:查看系统属性
VM.uptime [-date]:查看VM运行时间
VM.version:查看JVM版本信息
(3)使用:
jcmd 进程ID PerfCounter.print #查看此进程上可用的性能计数器
jcmd 启动类全名 PerfCounter.print #查看此启动类应用上可用的性能计数器
jcmd 进程ID Compiler.codecache #查看此进程代码缓存的布局+边界
5.jhat:
(1)格式:
jhat -命令 文件名.hprof
(2)命令列表:
-stack false或true:打开(默认)/关闭对象分配调用栈的跟踪
-refs false或true:打开(默认)/关闭对象引用的跟踪
-port 端口:(默认7000)设置jhat http server端口
-exclude 文件:此文件包含的数据成员,被排除在reachableFrom查询之外
-baseline 文件:指定基线对象转储,对象具有相同ID和相同类的两个堆转储将被标记为不是“新”。
-debug n:设置调试级别,n值为0(无调试输出)、1(调试hprof文件解析)、2(调试hprof文件解析,没有服务器)
-version:查看版本号
(3)使用:
jhat -stack true -refs true 文件名.hprof #打开对象分配调用栈+对象引用的跟踪
三、带界面的监控/故障排查软件:
1.jhsdb(jdk9+):
(1)jhsdb clhsdb:
jhsdb clhsdb --pid 进程ID #打开交互式命令行调试器
(2)jhsdb hsdb:
jhsdb hsdb --pid 进程ID #打开Java Threads调试器界面
(3)jhsdb jinfo:
命令:
--flags:查看VM标志
--sysprops:查看系统属性
使用:
jhsdb jinfo --pid 进程ID #查看此进程VM标志+系统属性
jhsdb jinfo --flags --pid 进程ID #查看此进程VM标志
jhsdb jinfo --sysprops --pid 进程ID #查看此进程系统属性
(4)jhsdb jmap:
命令:
--heap:查看堆概要信息
--binaryheap:dump堆为hprof格式
--dumpfile 文件名.hprof:设置dump文件名,可与--binaryheap一起使用
--histo:查看堆直方图
--clstats:查看堆类加载器统计信息
--finalizerinfo:查看等待结束的对象的信息
使用:
jhsdb jmap 命令 --pid 进程ID #格式
jhsdb jmap --binaryheap --dumpfile 文件名.hprof --pid 进程ID #将些进程堆dump到文件名.hprof
(5)jhsdb jstack:
命令:
--locks:查看Concurrent锁信息
--mixed:查看Java栈+本地方法栈信息
使用:
jhsdb jstack --locks --mixed --pid 进程ID
(6)jhsdb jsnap:
jhsdb jsnap --all --pid 进程ID #查看所有性能计数器信息
(7)jhsdb debugd:
jhsdb debugd 进程ID [server-id] #启动远程调试器服务器
2.jconsole:
(1)启动软件:
C:\Users\Administrator>jconsole
(2)新建连接,如图:
(3)查看概览内存/线程/类/VM概要/MBean信息(点击顶部选项卡切换),如图:
3.VisualVM(jdk8自带,jdk9+需要下载):
jdk9+版本下载地址:
http://visualvm.github.io/download.html
(1)启动软件:
C:\Users\Administrator>jvisualvm #jdk8自带版本启动
(2)监控信息查看(双击左侧VisualVM):
概述(简要信息,等同jps/jinfo命令):
监视CPU/堆Metaspace/类/线程(堆Dump类似jmap dump命令):
查看线程状态(线程Dump类似jstack命令):
抽样器(实时分析CPU/内存):
4.JMC(jdk10及以下自带,jdk11需要下载):
jdk11版本下载地址:
https://jdk.java.net/jmc/8/
被监控Web应用jdk<11,启动时加参数:
-XX:+UnlockCommercialFeatures -XX:+FlightRecorder
(1)启动软件:
C:\Users\Administrator>jmc #jdk8自带版本启动
(2)JMX监控数据(概览/MBean浏览器/触发器/系统/内存/线程/诊断命令):
(3)JFR诊断/性能分析(一般信息/内存/代码/IO/系统/事件)(概览/JVM信息/系统属性/记录):
5.MAT(堆内存分析器):
下载地址(解压双击MemoryAnalyzer.exe打开):
http://www.eclipse.org/mat/downloads.php
(1)效果如图:
(2)信息解释:
<1>Inspector(对象信息):
如内存地址、类名、包名、class地址、类加载器、堆大小、对象保留大小等
<2>Statics/Attributes(属性):
类静态属性/对象实例属性列表
<3>右则图标菜单:概览、直方图、支配树、OQL、线程视图、报告、功能列表、按地址查找等
<4>Biggest Objects by Retained Size(保留大小占比):
显示Retained Size对象占比图
<5>Actions(分析动作):
Histogram: 列出每个类的实例数
Dominator Tree: 列出最大的对象和存活原因。
Top Consumers:按类和包分组的最昂贵的对象。
Duplicate Classes: 检测被多个类加载器加载的类。
<6>Reports(报表):
Leak Suspects: 内存泄露原因,定位到指定类。
Top Components: 列出堆中比重>1%组件的报告。
<7>Step By Step(使用指南):
Component Report: 分析属于公共根包或类加载器的对象。
<8>Navigation History:
执行过的分析动作历史记录
6.JITWatch(日志分析器):
(1)下载并安装Cygwin64(额外勾选make、gcc-core、mingw64-x86_64-gcc-core、texinfo):
http://www.cygwin.cn/site/install/
(2)HSDIS安装(查看汇编):
<1>下载OpenJDK zip源码,并解压到D盘根目录(此处jdk8版本):
http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/tags
<2>将上面解压的D:\hotspot-818b1963f7a2\src\share\tools\hsdis目录拷贝到D根目录(D:\hsdis)。
<3>下载HSDIS源码,并解压为D:\binutils-2.27:
http://ftp.jaist.ac.jp/pub/GNU/binutils/
<4>打开d:\hsdis\Makefile,修改内容:
LIBRARIES = $(TARGET_DIR)/bfd/libbfd.a \
$(TARGET_DIR)/zlib/libz.a \
$(TARGET_DIR)/opcodes/libopcodes.a \
$(TARGET_DIR)/libiberty/libiberty.a
$(TARGET): $(SOURCE) $(LIBS) $(LIBRARIES) $(TARGET_DIR)
$(CC) $(OUTFLAGS) $(CPPFLAGS) $(CFLAGS) $(SOURCE) $(DLDFLAGS) $(LIBRARIES) -static -lz
<5>打开Cygwin终端,编译HSDIS(cd d:/hsdis):
$ make OS=Linux MINGW=x86_64-w64-mingw32 'AR=$(MINGW)-ar' BINUTILS=D:/binutils-2.27
<6>将生成的d:\hsdis\build\Linux-amd64文件拷贝到D:\Program Files\Java\jre\bin\server目录。
(2)启动Web应用生成info.log文件:
D:>java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -Xcomp -XX:+LogCompilation -XX:LogFile=D:\info.log -XX:+TraceClassLoading -jar usercenter-1.0.0.jar
(3)JITWatch(乱码未解决):
<1>下载JITWatch并解压为jitwatch-master:
https://github.com/AdoptOpenJDK/jitwatch
<2>启动JITWatch(cd d:\jitwatch-master目录):
D:\jitwatch-master>mvn clean compile exec:java
<3>导入info.log(Open Log -> 选择D:\info.log):
<4>导入源码(Config -> Add Folder选择Web应用工程目录 -> 点击Add JDK src -> Save):
<5>点菜单栏"Start"按钮启动Log分析(等右侧出现方法后,点某个方法弹出分析界面(源码 | 字节码 | 汇编码)):
四、远程连接:
1.JMX远程连接:
(1)远程主机防火墙开放/查看端口:
[root@localhost ~]# firewall-cmd --zone=public --add-port=1099/tcp --permanent
[root@localhost ~]# firewall-cmd --zone=public --add-port=1100/tcp --permanent
[root@localhost ~]# firewall-cmd --reload
[root@localhost ~]# firewall-cmd --zone=public --list-ports
(2)配置认证(远程主机上):
创建账号文件(vi account.jmxremote),内容:
root readwrite #读写权限,只读为readonly
创建密码文件(vi password.jmxremote),内容:
root root123456 #账号为root,密码为root123456
设置2个文件的权限:
[root@localhost ~]# chmod 600 account.jmxremote
[root@localhost ~]# chmod 600 password.jmxremote
(3)配置SSL(远程主机上):
<1>创建客户端Keystore(下载到本机):
[root@localhost ~]# keytool -genkeypair -alias client-ks -keyalg RSA -validity 365 -storetype pkcs12 -keystore client.keystore -storepass root123456 -keypass root123456 -dname "CN=yyh, OU=HLW, O=HLW, L=HZ, S=ZJ, C=ZH"
<2>导出客户端cert(下载到本机):
[root@localhost ~]# keytool -exportcert -alias client-ks -storetype pkcs12 -keystore client.keystore -file client.cer -storepass root123456
<3>创建服务端Keystore:
[root@localhost ~]# keytool -genkeypair -alias server-ks -keyalg RSA -validity 365 -storetype pkcs12 -keystore server.keystore -storepass root123456 -keypass root123456 -dname "CN=yyh, OU=HLW, O=HLW, L=HZ, S=ZJ, C=ZH"
<4>导出服务端cert:
[root@localhost ~]# keytool -exportcert -alias server-ks -storetype pkcs12 -keystore server.keystore -file server.cer -storepass root123456
<5>生成客户端truststore(将服务端cert导入生成)(下载到本机):
[root@localhost ~]# keytool -importcert -alias server-ks -file server.cer -keystore client.truststore -storepass root123456 -noprompt
<6>生成服务端truststore(将客户端cert导入生成):
[root@localhost ~]# keytool -importcert -alias client-ks -file client.cer -keystore server.truststore -storepass root123456 -noprompt
(4)监控远程主机Web应用:
<1>启动远程Web应用(启用访问认证+ssl):
[root@localhost ~]# java -Djava.rmi.server.hostname=192.168.233.130 \
-Dcom.sun.management.jmxremote.port=1099 \
-Dcom.sun.management.jmxremote.rmi.port=1100 \
-Dcom.sun.management.jmxremote.authenticate=true \
-Dcom.sun.management.jmxremote.access.file=./account.jmxremote \
-Dcom.sun.management.jmxremote.password.file=./password.jmxremote \
-Dcom.sun.management.jmxremote.ssl=true \
-Djavax.net.ssl.keyStore=/root/server.keystore \
-Djavax.net.ssl.keyStorePassword=root123456 \
-Djavax.net.ssl.trustStore=/root/server.truststore \
-Djavax.net.ssl.trustStorePassword=root123456 \
-jar usercenter-1.0.0.jar &
(2)本机启动VisualVM软件:
C:\Users\Administrator>jvisualvm -J-Djavax.net.ssl.keyStore=D:\client.keystore -J-Djavax.net.ssl.keyStorePassword=root123456 -J-Djavax.net.ssl.trustStore=D:\client.truststore -J-Djavax.net.ssl.trustStorePassword=root123456
(3)本机VisualVM监控远程Web应用(菜单栏文件 -> 添加JMX连接):
2.SSH远程连接:
(1)启动远程Web应用:
[root@localhost ~]# java -Djava.rmi.server.hostname=192.168.233.130 \
-Dcom.sun.management.jmxremote.port=1099 \
-Dcom.sun.management.jmxremote.rmi.port=1100 \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false \
-jar usercenter-1.0.0.jar &
(2)本机启动VisualVM软件:
C:\Users\Administrator>jvisualvm
(3)本机VisualVM配置代理(菜单栏工具 -> 选项 -> 网络):
(4)本机VisualVM监控远程Web应用(菜单栏文件 -> 添加JMX连接):