目录
jmap -histo PID> ./temp/temp.txt
jhat(java Heap Analysis Tool):(一般使用VisualVM代替jhat)
jmap(Java Memory Map):
概念:
-
java内存映像工具,用于生成堆快照(堆快照被称为heap dump)、查询java堆、永久代的详细信息、查询finalize执行队列(F-Queue)。
场景:
-
堆内存飙升、Full GC等gc异常时,通过VisualVM来分析堆的转储文件来定位问题。
-
排查步骤:
-
jmap PID 转储堆快照
-
通过VisualVM来分析堆的转储文件来定位问题
-
命令:
-
jmap [option] PID
jmap -histo PID> ./temp/temp.txt
-
Options:
-
-dump[:子参数] 生成java堆的快照。
-
live dump only live objects; if not specified, all objects in the heap are dumped.
-
format=b binary format
-
file=fileName
-
举例:eg:jmap -dump:live,format=b,file=heapDump.bin PID
-
-
说明:该参数的子参数比较难记,故使用时:jmap直接回车,在-dump参数的解释中有example。
-
-
-heap
-
显示java堆的详细信息。
-
-
-histo[:子参数]
-
统计java堆中的对象信息,子参数只有一个live(作用同-dump的字参数live)。
-
-
-finalizerinfo
-
显示在F-Queue中等待 Finalizer线程 执行finalize方法的对象。
-
-
-permstat
-
显示永久代的状态。
-
-
-F
-
Use with -dump or -histo to force a heap dump or histogram when pid does not respond. The "live" suboption is not supported in this mode.
-
-
常用命令:
堆转储: jmap -dump:format=b,file=heapDump.bin PID
统计堆中各类型对象的数量:
jmap -histo PID> ./temp/temp.txt
统计堆中存活对象的数量:
-
命令:jmap -histo:live PID> ./temp/temp2.txt
-
结果:
num #instances #bytes class name
1: 22049102 859951024 [C
2: 21758045 522193080 java.lang.String
3: 1576903 499085680 [B
4: 2485149 278336688 com.xxx.dto.MCRecordDetail
5: 7592189 182212536 java.lang.Long
6: 2498302 59959248 java.util.Date
7: 208692 45941384 [I
8: 311973 32390848 [Ljava.lang.Object;
9: 668 21899712 [Ljava.util.concurrent.ForkJoinTask;
10: 613551 19633632 java.util.HashMap$Node
11: 1130265 18084240 java.lang.Integer
12: 104663 11772944 [Ljava.util.HashMap$Node;
13: 171028 8209344 java.util.HashMap
14: 125504 6120224 [Ljava.lang.String;
15: 90864 5743424 [[B
16: 223564 5365536 java.util.ArrayList
-
说明:
-
统计结果是降序排列的。
-
不同类型数组的class name:
-
[C 表示 char[],String内部使用final char[]数组来存储数据
-
[S 表示 short[]
-
[I 表示 int[]
-
[B 表示 byte[]
-
[[I 表示 int[][]
-
-
jhat(java Heap Analysis Tool):(一般使用VisualVM代替jhat)
概念:
-
java堆(快照)分析工具,通常与jmap一起使用,使用jhat来分析jmap生成的堆快照。
-
说明:
-
jhat内置了一个微型的HTTP/HTML服务器,使用jhat对heap dump进行分析后,可以在浏览器中查看分析的结果,查看地址:http://localhost:7000
-
我们一般会使用一些更加高级的工具(eg:VisualVM、Eclipse Memory Analyzer)来分析heap dump,而不是使用jhat来分析heap dump
-
命令:
-
jhat /data/test/heapDump.bin
-
VisualVM 查看dump文件:
-
在jdk的安装目录下找到 bin/jvisualvm 命令,启动VisualVM
-
文件 --> 装入 --> 在弹出的窗口中 [文件格式:] 选择 [堆 Dump (*.hprof,*.*)] 后,选中dump文件即可。
-
注意:dump文件后缀必须为.bin或.hprof ,若不是则需要先修改dump文件的后缀,否则识别不了。
-
jstack(Java Stack Trace)
概念:
-
java栈跟踪工具,用来生成虚拟机当前时刻的线程快照(线程快照被称为thread dump或javacore文件)
场景:
-
cpu突然飙高问题排查:cpu飙高,一般是某个请求占用了大量资源导致,场景场景:死循环、线程间发生了死锁、请求外部资源导致的长时间等待。
-
排查步骤:
-
转储栈信息:jstack PID > /data/test/threadDumpFile
-
找到耗时的线程id:
-
top -Hp PID 找到占用大量cpu的线程id(十进制)。
-
将十进制的ID转换为十六进制的ID:printf "%x\n" 十进制的ID
-
在转储的栈信息中,根据十六进制的线程Id查看该线程的情况。
-
-
命令:
-
jstack [option] PID
-
Options:
-
-F to force a thread dump. Use when jstack <pid> does not respond (process is hung)
-
-m to print both java and native frames (mixed mode)
-
-l long listing. Prints additional information about locks
-
-h or -help to print this help message
-
常用命令:
-
转储堆栈信息:jstack PID > /data/test/threadDumpFile
-
统计所有的线程分别处于什么状态:jstack PID | grep java.lang.Thread.State | awk '{print $2$3$4$5}' | sort | uniq -c
注意:
-
dump出来的线程ID(nid的值就是线程ID)是十六进制的,而我们用TOP命令看到的线程ID是十进制的。
-
使用printf命令进行进制转换:
-
将十进制的ID转换为十六进制的ID:printf "%x\n" 十进制的ID
-
将十六进制的ID转换为十进制的ID:printf "%d\n" 十六进制的ID
-
jstat:
概念:
-
虚拟机统计信息工具(JVM Statistics Monitoring Tool),监视虚拟机的各种运行状态:类装载、内存、垃圾收集等运行数据。
命令:
-
jstat [option] PID [interval] [count]
-
option:
-
-class 查看类装载的信息
-
-gc 查看java堆的状况
-
-gccapacity 查看堆中各个区域的最小容量和最大容量
-
-gcutil 查看堆中各个区域已使用空间占其总空间的百分比
-
-gccause 与-gcutil相同,另外还输出了:导致上一次GC的原因和当前GC的原因
-
-gcnew 查看堆中新生代的状况
-
-gcnewcapacity 查看堆中新生代的最小容量和最大容量
-
-gcold 查看堆中老年代的状况
-
-gcoldcapacity 查看堆中老年代的最小容量和最大容量
-
-gcpermcapacity 查看堆中永久代的最小容量和最大容量
-
-gcmetacapacity 查看元数据空间的当前大小、最大容量和最小容量(jdk1.8)
-
-
interval: 表示查询的间隔时间,单位:毫秒
-
count: 表示查询的次数,如果interval和count都省略,则默认为只查询一次。
统计结果:
-
Minor GC(Young GC):
-
YGC: 进程从启动以来Minor GC的次数
-
YGCT:进程从启动以来Minor GC所花费的时间
-
-
Full GC:FGC表示次数,FGCT表示时间
-
FGC: 进程从启动以来Full GC的次数
-
FGCT:进程从启动以来Full GC所花费的时间
-
GCT: Minor GC和Full GC总共花费的时间
-
-
新生代(Young)中的Eden区:E
-
E: Eden区已使用的空间占其总空间的百分比
-
EC:Eden区的容量(Eden Capacity)
-
EU:Eden区已使用的空间(Eden Use)
-
-
新生代(Young)中的Survivor区:S0 S1
-
老年代(Old):O
-
永久代(Permanent):P
-
元数据空间(Metaspace):M
-
元数据空间中的压缩类空间(Compressed Class Space):CCS
-
1>jdk8中已经没有永久代了,取而代之的是元空间,元空间占用的是本地内存,不占用虚拟机的内存。
-
2>Metaspace由Klass Metaspace和NoKlass Metaspace两部分组成。
-
3>M表示Metaspace已使用的百分比,CCS表示Klass Metaspace已使用的百分比(CCS=CCSU/CCSC)。
-
4>M的值达到了90%以上,不一定能说明metaspace已经用了很多了,因为内存是慢慢commit的,所以我们的分母是慢慢变大的,不过当我们commit到一定量的时候就不会再增长了。
-
5>根据MC,MU,CCSC,CCSU来判断metaspace的状态更靠谱。(注:可以在jstat -gc 中看到MU)
-
-
说明:
-
S0/S0C/S0U、S1/S1C/S1U、O/OC/OU、P/PC/PU、M/MC/MU、CCS/CCSC/CCSU 与 E/EC/EU类似
-
-
LGCC:最后一次GC发生的原因
-
GCC: 当前GC发生的原因
-
容量大小:单位是KB
-
NGCMN:新生代的最小(初始化)容量
-
NGCMX:新生代的最大容量NGC: 新生代当前的容量
-
ECMX: 新生代中Eden区的最大容量
-
S0CMX、S1CMX:新生代中Survivor区的最大容量
-
OGCMN:老年代的最小(初始化)容量
-
OGCMX:老年代的最大容量OGC: 老年代当前的容量
-
PGCMN:永久代的最小(初始化)容量
-
PGCMX:永久代的最大容量PGC: 永久代当前的容量
-
MCMN: 元数据空间最小容量
-
MCMX: 元数据空间最大容量
-
MC: 当前元数据空间的大小
-
CCSMN: 压缩类空间CCS(即:Klass Metaspace)的最小容量
-
CCSMX: 压缩类空间CCS(即:Klass Metaspace)的最大容量
-
CCSC: 当前压缩类空间CCS(即:Klass Metaspace)的大小
-
-
TT: 老年化阈值。被移动到老年代之前,在新生代空存活的次数
-
MTT:最大老年化阈值。
-
DSS:幸存者区所需空间大小
常用命令:
-
jstat -gc
-
jstat -gcutil
-
jstat -gccause
-
jstat -gccapacity
-
jstat -gcnew
常见问题:
-
使用jdk自带的小工具报错:sun.jvm.hotspot.runtime.VMVersionMismatchException
-
解决:这是由于jvm的版本不匹配导致,找到该java进程的启动命令,然后使用进程启动命令(即java命令)所在文件夹中的jdk小工具即可。
jinfo工具
概念:
查看java进程(JVM)的配置信息。注意:该命令不能在mac上使用,否则会导致java进程挂掉!
命令:
jinfo PID
查询结果:
-
配置信息:
-
Java System Properties:
-
java.class.path
-
user.dir
-
file.encoding
-
-
VM Flags(虚拟机参数):
-
-XX:InitialHeapSize=xxx 注:单位是字节。
-
-XX:MaxHeapSize=xxxx
-
-XX:+UseConcMarkSweepGC
-
-XX:+UseParNewGC
-
-XX:+UseParallelGC
-
-
Command line(进程启动命令中的参数):
-
-Xms4096m
-
-Xmx4096m
-
-Dfile.encoding=UTF-8
-
jcmd
概念:
-
jcmd用于向正在运行的JVM发送诊断信息请求(since JDK1.7),功能与jstack类似。
常用:
-
jcmd PID help
-
# 查看能从目标进程中获取到的信息
-
-
jcmd PID VM.flags
-
# 查看JVM的启动参数,容量大小的单位是字节。
-
-
jcmd PID Thread.print
-
# 查看JVM的Thread Dump,类似于jstack PID
-
-
jcmd PID GC.heap_dump 转储文件的名称
-
# 查看JVM的Heap Dump,类似于 jmap -dump:format=b,file=heapDump.bin PID
-
-
jcmd -l
-
# 列出当前所有运行的java进程,与jps命令的作用一样。
-
-
jcmd PID VM.version
-
# 查看JVM的版本信息
-
-
jcmd PID VM.system_properties
-
# 查看JVM的系统属性,eg:java.home=xxxx
-
# 举例:进程启动命令中的java命令的安装路径,并不是 ${JAVA_HOME} 的值!代码中可通过System.getProperty("java.home")获取改值。
-
-
jcmd PID GC.class_histogram
-
# 查看JVM的类信息:每个类的实例数量和占用空间大小
-
-
jcmd PID PerfCounter.print
-
# 查看 JVM 性能相关的参数
-
jps:
概念:
-
查看虚拟机进程信息工具(JVM Process Status Tool),用来查看所有java进程的信息
命令:
-
jps [options] [hostid]
-
options:
-
–q:只查看java进程的进程号
-
-m:查看main method的参数
-
–l:查看主类的完全限定名或jar的完全路径名
-
-v:查看jvm参数
-
-V:输出通过flag文件传递到JVM中的参数(.hotspotrc文件或-XX:Flags=所指定的文件
-
-
hostid:
-
[protocol:][[//]hostname][:port][/servername]
-
常用:
-
jps –q
-
# 查看java进程的进程号
-
-
jps -m
-
# 查看main method的参数
-
-
jps –l
-
# 查看主类的完全限定名或jar的完全路径名
-
-
jps –v
-
# 查看jvm参数
-