jstack 栈分析
A.找出进程
[root@c100 ~]# jps |grep jar
2181jar
2.找出最耗CPU的线程
[root@c100 ~]# top -Hp 2181
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2181 root 20 0 2322404 537720 11620 S 0.0 13.8 0:00.02 java
2182 root 20 0 2322404 537720 11620 S 0.0 13.8 0:00.39 java
2183 root 20 0 2322404 537720 11620 S 0.0 13.8 0:00.34 java
2184 root 20 0 2322404 537720 11620 S 0.0 13.8 0:00.34 java
2185 root 20 0 2322404 537720 11620 S 0.0 13.8 0:00.19 java
3. 线程ID转换为16进制
[root@c100 ~]# printf "%x\n" 2182
886
#4. 输出堆栈信息并分析耗时原因
[root@c100 ~]# jstack 2181 | grep 886
"DestroyJavaVM" prio=10 tid=0x00007f6564008800 nid=0x886 waiting on condition [0x0000000000000000]
B. jmap 堆内存分析
1. 打印持久代对象信息
输出:类加载器名称、对象是否存活(不可靠)、对象地址、父类加载器、已加载的类大小等信息
jmap -permstat 2181
2. 使用jmap -heap pid查看进程堆内存使用情况,包括使用的GC算法、堆配置参数和各代中堆内存使用情况。
jmap -heap 2181
3. 使用jmap -histo[:live] pid查看堆内存中的对象数目、大小统计直方图,如果带上live则只统计活对象
jmap -histo:live 2181 | more
4. 用jmap把进程内存使用情况dump到文件中用jhat分析查看
jmap -dump:format=b,file=/tmp/dump.dat 2181
jhat -port 10086 /tmp/dump.dat
C. jstat(JVM统计监测工具)
语法格式如下
jstat [ generalOption | outputOptions vmid [interval[s|ms] [count]] ]
- vmid是虚拟机ID,在Linux/Unix系统上一般就是进程ID。
- interval是采样时间间隔。
- count是采样数目。
- 比如下面输出的是GC信息、进程2181、采样间隔500ms、采样数为10
[root@c100 ~]# jstat -gc 2181 500 10
S0C S1C S0U S1U EC EU OC OU PC PU YGC YGCT FGC FGCT GCT
11776.0 11264.0 0.0 0.0 300544.0 4120.7 78336.0 37001.1 68608.0 35256.5 15 0.309 2 0.558 0.866
11776.0 11264.0 0.0 0.0 300544.0 4120.7 78336.0 37001.1 68608.0 35256.5 15 0.309 2 0.558 0.866
11776.0 11264.0 0.0 0.0 300544.0 4120.7 78336.0 37001.1 68608.0 35256.5 15 0.309 2 0.558 0.866
11776.0 11264.0 0.0 0.0 300544.0 4120.7 78336.0 37001.1 68608.0 35256.5 15 0.309 2 0.558 0.866
11776.0 11264.0 0.0 0.0 300544.0 4120.7 78336.0 37001.1 68608.0 35256.5 15 0.309 2 0.558 0.866
- S0C、S1C、S0U、S1U:Survivor 0/1区容量(Capacity)和使用量(Used)
- EC、EU:Eden区容量和使用量
- OC、OU:年老代容量和使用量
- PC、PU:永久代容量和使用量
- YGC、YGT:年轻代GC次数和GC耗时
- FGC、FGCT:Full GC次数和Full GC耗时
- GCT:GC总耗时