一、jmap
1.1 概述
命令jmap是一个多功能的命令。它可以生成 java 程序的 dump 文件, 也可以查看堆内对象示例的统计信息、查看 ClassLoader 的信息以及 finalizer 队列。
1.2 收集Dump文件
在实际生产环境过程中,我们会通过收集Dump文件,来分析内存溢出的情况,但是一般在大数据的场景下出现严重的FULL GC的时候,我们都不会直接使用jmap的收集命令来收集,这样很耗时,也会导致服务器卡顿,影响其它应用正常使用,所以一般是在测试环境中进行模拟,来收集dump 文件,或者在启动应用程序的时候设置发生内存溢出时,JVM会自动将堆转储。
方式一:通过jmap命令收集Dump文件
jmap -dump:live,format=b,file=/opt/jvm/dump.hprof pid
方式二:设置JVM启动参数
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/jvmdump
java -jar -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/jvmdump dt-boot-java.jar
在每次发生内存溢出时,JVM会自动将堆转储,dump文件存放在-XX:HeapDumpPath指定的路径下。
如下图,当我们程序发生OOM堆内存溢出的时候,dump文件已经生成了。
1.3 分析Dump文件
可以使用Java VisualVM是jdk自带一款工具,jdk的bin目录下,找到jvisualvm.exe,双击打开即可,然后装入dump文件,如下图所示:
1.4 显示Java堆详细信息
jmap -heap pid
[root@hadoop01 ~]# jmap -heap 5992
Attaching to process ID 5992, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.321-b07
using thread-local object allocation.
Parallel GC with 4 thread(s)
Heap Configuration:
MinHeapFreeRatio = 0
MaxHeapFreeRatio = 100
MaxHeapSize = 478150656 (456.0MB)
NewSize = 10485760 (10.0MB)
MaxNewSize = 159383552 (152.0MB)
OldSize = 20971520 (20.0MB)
NewRatio = 2
SurvivorRatio = 8
MetaspaceSize = 21807104 (20.796875MB)
CompressedClassSpaceSize = 1073741824 (1024.0MB)
MaxMetaspaceSize = 17592186044415 MB
G1HeapRegionSize = 0 (0.0MB)
Heap Usage:
PS Young Generation
Eden Space:
capacity = 100663296 (96.0MB)
used = 100369080 (95.71941375732422MB)
free = 294216 (0.28058624267578125MB)
99.7077226638794% used
From Space:
capacity = 19922944 (19.0MB)
used = 19909064 (18.98676300048828MB)
free = 13880 (0.01323699951171875MB)
99.93033158151727% used
To Space:
capacity = 29360128 (28.0MB)
used = 0 (0.0MB)
free = 29360128 (28.0MB)
0.0% used
PS Old Generation
capacity = 73924608 (70.5MB)
used = 39087064 (37.276329040527344MB)
free = 34837544 (33.223670959472656MB)
52.87422558940049% used
1140 interned Strings occupying 80480 bytes.
1.5 显示堆中对象的统计信息
jmap -histo:live pid
[root@hadoop01 ~]# jmap -histo:live 6091
num #instances #bytes class name
----------------------------------------------
1: 1495238 35885712 com.example.java.cpu.HignCpu
2: 830 7330272 [Ljava.lang.Object;
3: 1657 130568 [C
4: 682 77960 java.lang.Class
5: 1643 39432 java.lang.String
6: 38 25896 [B
7: 147 12936 java.lang.reflect.Method
8: 207 11592 java.lang.invoke.MemberName
9: 262 8384 java.util.concurrent.ConcurrentHashMap$Node
10: 272 8176 [Ljava.lang.Class;
11: 111 7992 java.lang.reflect.Field
12: 171 7472 [I
13: 179 7160 java.lang.ref.SoftReference
14: 221 7072 java.lang.invoke.LambdaForm$Name
15: 256 6144 java.lang.Long
二、jstack
2.1 概述
jstack是JVM自带的Java堆栈跟踪工具,它用于打印出给定的java进程ID、core file、远程调试服务的Java堆栈信息。
2.2 jstack分析CPU过高步骤
2.2.1 top
在服务器上,我们可以通过top命令查看各个进程的cpu使用情况,它默认是按cpu使用率由高到低排序的。
top
2.2.2 top -Hp pid
top -Hp pid
2.2.3 jstack pid
printf "%x\n" 6214
jstack 6199 | grep 1846
jstack 6199 >> my.dump
三、arthas(阿尔萨斯)
3.1 概述
Arthas 是一款线上监控诊断产品,通过全局视角实时查看应用 load、内存、gc、线程的状态信息,并能在不修改应用代码的情况下,对业务问题进行诊断,包括查看方法调用的出入参、异常,监测方法执行耗时,类加载信息等,大大提升线上问题排查效率。
3.2 安装
curl -O https://arthas.aliyun.com/arthas-boot.jar
3.3 启动
java -jar arthas-boot.jar
选择需要监控进程前的序号,输入 1
,再Enter 回车,便会打印 arthas 的banner
:
1)输入dashboard
,回车,仪表盘显示当前进程相关信息。
分为三个部分:第一部分为cpu监控,第二部分为内存监控,第三部分为环境信息
2) 执行thread
,查看所有的线程
3)查看CPU使用率top n线程的栈 :thread -n 3
4)thread pid
命令会打印线程ID 的栈
5)sc
命令来查找JVM里已加载的类:
6)jad
命令来反编译代码
总结
上面我们学习了JVM的一些命令,以及工具,最终目标的不仅仅是了解这些命令的基础知识,也是为了进行JVM性能调优做准备。