常用
1 | # 解决 docker 容器不能使用 jmap |
jps
虚拟机进程状况工具
1 | jps # 查看 pid |
jinfo
Java配置信息工具
1 | jinfo -flags 7 # 输出配置信息 |
JVM 参数
1 | -Dxxx 标注参数 |
1 | java -version # 查看java版本 |
jstat
虚拟机统计信息监视工具
jstat -class 7
1
2
3
4
5
6
7
8
9
10Loaded Bytes Unloaded Bytes Time
17778 33005.8 114 150.1 5503.66
Loaded 加载多少类
Bytes 占用字节数
Unloaded 不加载的类
Bytes 占用字节数
Time 加载耗时jstat -gcutil 7 1000
一秒打印1次 gc日志。也可以加上次数,例如打印3次jstat -gcutil 7 1000 3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
21.80 0.00 33.85 37.65 95.24 92.86 3325 949.517 4 5.613 955.130
21.80 0.00 34.03 37.65 95.24 92.86 3325 949.517 4 5.613 955.130
21.80 0.00 34.23 37.65 95.24 92.86 3325 949.517 4 5.613 955.130
21.80 0.00 34.25 37.65 95.24 92.86 3325 949.517 4 5.613 955.130
S0:幸存1区当前使用比例
S1:幸存2区当前使用比例
E:伊甸园区使用比例
O:老年代使用比例
M:元数据区使用比例
CCS:压缩使用比例
YGC:年轻代垃圾回收次数
YGCT:年轻代垃圾回收消耗时间
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间
jmap
Java内存映射工具
生成堆储存快照,dump文件
jmap -heap 7
显示堆,及使用情况(具体含义,参考下面案例)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46Attaching to process ID 7, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.292-b10
using thread-local object allocation.
Parallel GC with 4 thread(s)
Heap Configuration:
MinHeapFreeRatio = 0
MaxHeapFreeRatio = 100
MaxHeapSize = 8589934592 (8192.0MB)
NewSize = 4294967296 (4096.0MB)
MaxNewSize = 4294967296 (4096.0MB)
OldSize = 4294967296 (4096.0MB)
NewRatio = 2
SurvivorRatio = 8
MetaspaceSize = 536870912 (512.0MB)
CompressedClassSpaceSize = 528482304 (504.0MB)
MaxMetaspaceSize = 536870912 (512.0MB)
G1HeapRegionSize = 0 (0.0MB)
Heap Usage:
PS Young Generation
Eden Space:
capacity = 3699376128 (3528.0MB)
used = 162589232 (155.0571746826172MB)
free = 3536786896 (3372.942825317383MB)
4.395044633861032% used
From Space:
capacity = 304611328 (290.5MB)
used = 57984432 (55.29826354980469MB)
free = 246626896 (235.2017364501953MB)
19.03554683297924% used
To Space:
capacity = 290979840 (277.5MB)
used = 0 (0.0MB)
free = 290979840 (277.5MB)
0.0% used
PS Old Generation
capacity = 4294967296 (4096.0MB)
used = 1970283200 (1879.0084838867188MB)
free = 2324684096 (2216.9915161132812MB)
45.874230563640594% used
41044 interned Strings occupying 4547200 bytes.
含义解释:
1 | # docker exec -it bff01 jmap -heap $(docker exec -it bff01 jps | grep jar | awk '{print $1}') |
jmap -histo 7 | head -n 15
显示所有 class的实例,数量,内存大小1
2
3
4
5
6
7
8
9
10
11
12
13
14num #instances #bytes class name
----------------------------------------------
1: 693235 535837592 [B
2: 4836578 487571688 [C
3: 4808399 115401576 java.lang.String
4: 1338286 106654600 [Ljava.lang.Object;
5: 2554225 102169000 java.util.LinkedHashMap$Entry
6: 1109240 88777440 [Ljava.util.WeakHashMap$Entry;
7: 131390 87379360 [I
8: 79970 74820496 [J
9: 1109233 53243184 java.util.WeakHashMap
10: 410747 46003664 org.springframework.boot.loader.jar.JarFile
11: 450870 38262672 [Ljava.util.HashMap$Node;
12: 1154904 36956928 java.lang.ref.ReferenceQueuejmap -dump:live,format=b,file=heap.bin 7
手动导出dump日志,不加路径默认导入到当前文件夹
jstack
Java堆栈跟踪工具
可以排查死锁
jstack 7 | grep deadlock
jstack 7 | grep Thread.State | sort | uniq
线程的状态有哪些1
2
3
4
5
6java.lang.Thread.State: RUNNABLE
java.lang.Thread.State: TIMED_WAITING (on object monitor)
java.lang.Thread.State: TIMED_WAITING (parking)
java.lang.Thread.State: TIMED_WAITING (sleeping)
java.lang.Thread.State: WAITING (on object monitor)
java.lang.Thread.State: WAITING (parking)jstack 7 | grep TaskThread- | awk '{print $1}' | sort -nt "-" -k 2 | cat -n
查看有哪些线程在跑(线程名称自己定义)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
191 "JdRdsFetchTaskThread-30"
2 "KafkaTaskThread-31"
3 "ApiFetchTaskThread-35"
4 "KafkaTaskThread-36"
5 "ApiFetchTaskThread-37"
6 "KafkaTaskThread-38"
7 "KafkaTaskThread-39"
8 "ApiFetchTaskThread-40"
9 "KafkaTaskThread-41"
10 "KafkaTaskThread-42"
11 "KafkaTaskThread-44"
12 "KafkaTaskThread-45"
13 "ApiFetchTaskThread-47"
14 "KafkaTaskThread-48"
15 "KafkaTaskThread-62"
16 "ApiFetchTaskThread-64"
17 "KafkaTaskThread-65"
18 "ApiFetchTaskThread-66"
19 "KafkaTaskThread-67"
CPU 100% 排查
1、执行java -cp app.jar -XX:+PrintGC -Xmx200M -Xmx200M com.taopanfeng.FullGCProblem
解释:最小堆200M,最大堆200M,并打印GC信息。使用 -cp app.jar 需要指定main方法的类 也就是 com.taopanfeng.FullGCProblem。
这个程序会一直往线程池队列中扔数据。每扔一条数据就要创建100个UserInfo对象。因为存在队列中,所以这100个对象不能被垃圾回收,所以内存会越来越占用过大。而我们启动时,设置堆内存200M又很小,所以会频繁GC。
2、top
命令,上面显示整理情况,下面显示进程。
为什么有些进程可以超过 100%,是因为下面是按照核心来算的。例如:两个核心,最大是200%。
上面显示的才是总的 cpu 使用率。
记住 pid 后面要用到。
3、top -p 5943
监控单个进程,进入监控界面,此时输入 H
显示进程下的所有线程。
占用过高的有两个线程 5945,5946。
4、使用工具 在线进制转换 ,把这两个线程换算成 16进制。
5、使用命令 jstack 5943
查看 java 进程的所有线程信息。搜索5945,5946的十六进制 1739,173a。
发现,两个线程都是 GC线程。CPU 都被 GC 给吃掉了。
6、查看 GC 信息。jstat -gcutil 5943 1000
一秒刷新一次,发现频繁的进行 full gc
7、jmap -heap 5943
查看堆的使用情况。eden from to都满了,old也 99%。所以,会频繁 full gc。
1 | # 内存过高还可能存在其他问题 |
8、查看到哪些对象占用过高
1 | class name对应的就是Class文件里的class的标识 |
OOM排查
方式1、启动前加入参数:-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./
,即使发生 OOM 也会有日志可以分析
详情参考:Java平台,标准版工具参考 - Java8官方文档
方式2、未发生 OOM,可以进行日志 dump 下面,使用工具进行分析。
未 OOM jmap -dump:live,format=b,file=heap.bin 7
导出dump日志,不加路径默认导入到当前文件夹