① jps: JVM Process status tool:JVM进程状态工具,查看进程基本信息
② jstat: JVM statistics monitoring tool : JVM统计监控工具,查看堆,GC详细信息
③ jinfo:Java Configuration Info :查看配置参数信息,支持部分参数运行时修改
④ jmap:Java Memory Map :分析堆内存工具,dump堆内存快照
⑤ jhat:Java Heap Analysis Tool :堆内存dump文件解析工具
⑥ jstack:Java Stack Trace :Java堆栈跟踪工具
⑦ VisualVM:性能分析可视化工具
注:前面6个为命令行,最后一个为性能分析可视化工具(不能在linux中使用)
① GCEasy:免费GC日志可视化分析Web工具
② MAT:Memory Analyzer Tool 可视化内存分析工具
③ GCViewer:开源的GC日志分析工具
④ Arthas:线上Java程序诊断工具,功能非常强大
#列出Java程序进程ID和Main函数名称
jps
#只输出进程ID
jps -q
#输出传递给Java进程(主函数)的参数 例如--spring.config.location
jps -m
#输出主函数的完整路径
jps -l
#显示传递给Java虚拟的参数
jps -v
options:由以下值构成
-class:显示ClassLoader的相关信息
-compiler:显示JIT编译的相关信息
-gc:显示与GC相关信息
-gccapacity:显示各个代的容量和使用情况
-gccause:显示垃圾收集相关信息(同-gcutil),同时显示最后一次或当前正在发生的垃圾收集的诱发原因
-gcnew:显示新生代信息
-gcnewcapacity:显示新生代大小和使用情况
-gcold:显示老年代信息
-gcoldcapacity:显示老年代大小
-gcpermcapacity:显示永久代大小
-gcutil:显示垃圾收集信息
#进程id 采样间隔250ms 采样数4
jstat -gc 30108 250 4
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:metaspace的容量 (单位kb)
MU:metaspace目前已使用空间 (单位kb)
CCSC:压缩类空间大小
CCSU:压缩类空间使用大小
YGC :从应用程序启动到采样时年轻代中gc次数
YGCT :从应用程序启动到采样时年轻代中gc所用时间(s)
FGC :从应用程序启动到采样时old代(全gc)gc次数
FGCT :从应用程序启动到采样时old代(全gc)gc所用时间(s)
GCT:从应用程序启动到采样时gc用的总时间(s)
#进程ID 26856 采样间隔1s 采样数5
jstat -gcutil 26856 1s 5
S0 年轻代中第一个survivor(幸存区)已使用的占当前容量百分比
S1 年轻代中第二个survivor(幸存区)已使用的占当前容量百分比
E 年轻代中Eden(伊甸园)已使用的占当前容量百分比
O old代已使用的占当前容量百分比
M metaspace已使用的占当前容量百分比
CCS 压缩使用比例
YGC 从应用程序启动到采样时年轻代中gc次数
YGCT 从应用程序启动到采样时年轻代中gc所用时间(s)
FGC 从应用程序启动到采样时old代(全gc)gc次数
FGCT 从应用程序启动到采样时old代(全gc)gc所用时间(s)
GCT 从应用程序启动到采样时gc用的总时间(s)
#参数选项 进程id
jinfo -flags 26856
jmap 26856 #进程号
查看进程的内存映像信息。使用不带选项参数的jmap打印共享对象映射,将会打印目标虚拟机中加载的每个共享对象的
起始地址、映射大小以及共享对象文件的路径全称。
#显示Java堆详细信息:打印堆的摘要信息,包括使用的GC算法、堆配置信息和各内存区域内存使用信息
jmap -heap 26856
jmap -histo:live 26856
显示堆中对象的统计信息:其中包括每个Java类、对象数量、内存大小(单位:字节)、完全限定的类名。打印的虚拟机内部的类名称将会带有一个’*’前缀。如果ja指定了live子选项,则只计算活动的对象。
jmap -clstats 26856
打印类加载器信息:打印Java堆内存的方法区的类加载器的智能统计信息。对于每个类加载器而言,它的名称、活跃度、
地址、父类加载器、它所加载的类的数量和大小都会被打印。此外,包含的字符串数量和大小也会被打印。
jmap -finalizerinfo 26856 #打印等待终结的对象信息
jmap -dump:format=b,file=heapdump.hprof 26856
生成堆转储快照dump文件:以二进制格式转储Java堆到指定文件中。如果指定了live子选项,堆中只有活动的对象会被转
储。浏览heap dump 可以使用jhat 读取生成的文件,也可以使用MAT等堆内存分析工具。
注意:这个命令执行,JVM会将整个heap的信息dump写入到一个文件,heap如果比较大的话,就会导致这个过程比较耗时,并且执
行的过程中为了保证dump的信息是可靠的,所以会暂停应用, 线上系统慎用!
5. Jhat :Java Heap Analysis Tool
jhat 命令会解析Java堆转储文件,并启动一个 web server。然后用浏览器来查看/浏览 dump 出来的 heap二进制文件。
jhat 命令支持预先设计的查询,比如:显示某个类的所有实例。还支持 对象查询语言(OQL)。 OQL有点类似SQL,专门用来
查询堆转储。
Java生成堆转储的方式有多种:
jhat [ options ] heap-dump-file
jmap -dump:format=b,file=demo.hprof 26856
jhat ./demo.hprof #可以启动一个服务端口是7000 查看堆的信息
jhat 启动后显示的 html 页面中包含有:
All classes including platform:显示出堆中所包含的所有的类
Show all members of the rootset :从根集能引用到的对象
Show instance counts for all classes (including platform/excluding platform):显示平台包括的所有类的实例数量
Show heap histogram:堆实例的分布表
Show finalizer summary:Finalizer 摘要
Execute Object Query Language (OQL) query:执行对象查询语句(OQL)
jstack [ option ] pid #查看当前时间点,指定进程的dump堆栈信息。
jstack [ option ] pid > #文件 将当前时间点的指定进程的dump堆栈信息,写入到指定文件中。
# 注:若该文件不存在,则会自动生成; 若该文件存在,则会覆盖源文件。
jstack [ option ] executable core# 查看当前时间点,core文件的dump堆栈信息。
jstack [ option ] [server_id@]<remote server IP or hostname> #查看当前时间点,远程机器的dump堆栈信息。
-F 当进程挂起了,此时’jstack [-l] pid’是没有相应的,这时候可使用此参数来强制打印堆栈信息,强制jstack),一般情况不
需要使用。
-m 打印java和native c/c++框架的所有栈信息。可以打印JVM的堆栈,以及Native的栈帧,一般应用排查不需要使用。
-l 长列表. 打印关于锁的附加信息。例如属于java.util.concurrent的ownable synchronizers列表,会使得JVM停顿得长久得多(可能会差很多倍,比如普通的jstack可能几毫秒和一次GC没区别,加了-l 就是近一秒的时间),-l 建议不要用。一般情况不需要使用。
-h or -hel 打印帮助信息
jstack 26856 #打印堆栈
jstack -l 26856 | grep 'java.lang.Thread.State' | wc -l 统计线程数量
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
-Djava.rmi.server.hostname=172.26.233.198
-Dcom.sun.management.jmxremote.rmi.port=9999
#JAVA_OPT="${JAVA_OPT} -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9999 -
Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -
Djava.rmi.server.hostname=123.56.254.18 -Dcom.sun.management.jmxremote.rmi.port=9999"
2. MAT
1)介绍
MAT是一个强大的可视化内存分析工具,可以快捷、有效地帮助我们找到内存泄露,减少内存消耗分析工具。MAT是Memory
Analyzer tool的缩写,是一种快速,功能丰富的Java堆分析工具,能帮助你查找内存泄漏和减少内存消耗。
功能:
找到最大的对象,因为MAT提供显示合理的累积大小(retained size)
探索对象图,包括inbound和outbound引用,即引用此对象的和此对象引出的
查找无法回收的对象,可以计算从垃圾收集器根到相关对象的路径
找到内存浪费,比如冗余的String对象,空集合对象。
MAT下载地址
注意需要下载支持JDK的版本:
MAT相关概念说明
1 内存泄漏与内存溢出
内存泄露:对象是垃圾了,还存在被GCRoots引用的情况,无法被垃圾收集器回收。
解决方案:找出泄漏的代码位置和原因,具体问题具体解决;
内存溢出:内存中的对象非常多,堆空间不足,就会出现。
解决方案:检查堆大小设置是否合理,检查是否存在对象生命周期太长、持有状态时间过长的情况。
2 shallow heap及retained heap
shallow heap:对象本身占用内存的大小,也就是对象内存区域的总和。
retained heap:对象及对象引用链中所有对象的大小总和,如果一个对象被释放掉,因为该对象的释放而被释放的所有的对象
的大小。相对于shallow heap,Retained heap可以更精确的反映一个对象实际占用的大小。
3 outgoing references与incoming references
outgoing references :表示该对象的出节点(被该对象引用的对象)。
incoming references :表示该对象的入节点(引用到该对象的对象)。
3 Dominator Tree
Dominator Tree对象的支配树:帮助我们快速的发现占用内存最大的块,也能帮我们分析对象之间的依赖关系。
分析GC
MAT工具使用
分析内存溢出
分析内存泄露
查看对象个数及对象内存占用
观察对象回收后释放空间大小
观察线程栈
#分析gc日志,打开图形化界面
java -jar gcviewer-1.36.jar gc.log
# 分析gc日志,不打卡图形化界面,将结果直接生成
java -jar gcviewer-1.36.jar gc.log summary.csv chart.png
# 下载arthas-boot.jar
curl -O https://alibaba.github.io/arthas/arthas-boot.jar
# 打印帮助信息:
java -jar arthas-boot.jar -h
# 启动
java -jar arthas-boot.jar
Arthas 常见命令
jvm:查看当前 JVM 的信息
thread:查看当前 JVM 的线程堆栈信息,
-b 选项可以一键检测死锁
-n 指定最忙的前N个线程并打印堆栈
-1 打印统计信息(数字1)
trace:方法内部调用路径,并输出方法路径上的每个节点上耗时,服务间调用时间过长时使用
stack:输出当前方法被调用的调用路径
Jad:反编译指定已加载类的源码,反编译便于理解业务
logger:查看和修改 logger,可以动态更新日志级别
支持管道:
Arthas支持使用管道对上述命令的结果进行进一步的处理,如 sm java.lang.String * | grep ‘index’
grep——搜索满足条件的结果
plaintext——将命令的结果去除ANSI颜色
wc——按行统计输出结果
后台异步任务:
当线上出现偶发的问题,比如需要watch某个条件,而这个条件一天可能才会出现一次时,异步后台任务就派上用场了,详情请参考
这里
使用 > 将结果重写向到日志文件,使用 & 指定命令是后台运行,session断开不影响任务执行(生命周期默认为1天)
jobs——列出所有job
kill——强制终止任务
fg——将暂停的任务拉到前台执行
bg——将暂停的任务放到后台执行
用户数据回报:
在 3.1.4 版本后,增加了用户数据回报功能,方便统一做安全或者历史数据统计。
在启动时,指定 stat-url ,就会回报执行的每一行命令,比如: ./as.sh --stat-url
‘http://192.168.10.11:8080/api/stat’
在tunnel server里有一个示例的回报代码,用户可以自己在服务器上实现
这里只列出常用命令,完整列表参考命令列表:https://github.com/alibaba/arthas/blob/master/README_CN.md
dashboard
thread -1 #会打印线程统计信息 这里是数字1
jap com.learn.lessonone.DemoController #反编译源码
watch com.learn.lessonone.DemoController getData returnObj#监控接口 controller getData是方法名,注意是方法名不是路径